Verifikasi kredensial digital dalam aplikasi Android dapat digunakan untuk mengautentikasi dan mengizinkan identitas pengguna (seperti tanda pengenal terbitan pemerintah), properti tentang pengguna tersebut (seperti surat izin mengemudi, gelar akademik, atau atribut seperti usia atau alamat), atau skenario lain saat kredensial perlu diterbitkan dan diverifikasi untuk menegaskan keaslian suatu entitas.
Verifier API didukung di Android 9 (API level 28) dan yang lebih tinggi.
Penerapan
Untuk memverifikasi kredensial digital di project Android Anda, lakukan hal berikut:
- Tambahkan dependensi ke skrip build aplikasi Anda dan lakukan inisialisasi
class
CredentialManager. - Buat permintaan kredensial digital dan gunakan untuk melakukan inisialisasi
DigitalCredentialOption, diikuti dengan mem-buildGetCredentialRequest. - Luncurkan alur
getCredentialdengan permintaan yang dibuat untuk menerimaGetCredentialResponseyang berhasil atau menangani pengecualian apa pun yang mungkin terjadi. Setelah pengambilan berhasil, validasi responsnya.
Menambahkan dependensi dan melakukan inisialisasi
Tambahkan dependensi berikut ke skrip build Gradle Anda:
dependencies {
implementation("androidx.credentials:credentials:1.6.0-beta01")
implementation("androidx.credentials:credentials-play-services-auth:1.6.0-beta01")
}
Selanjutnya, lakukan inisialisasi instance class CredentialManager.
val credentialManager = CredentialManager.create(context)
Membuat permintaan kredensial digital
Buat permintaan kredensial digital dan gunakan untuk melakukan inisialisasi
DigitalCredentialOption.
// The request in the JSON format to conform with
// the JSON-ified Credential Manager - Verifier API request definition.
val requestJson = generateRequestFromServer()
val digitalCredentialOption =
GetDigitalCredentialOption(requestJson = requestJson)
// Use the option from the previous step to build the `GetCredentialRequest`.
val getCredRequest = GetCredentialRequest(
listOf(digitalCredentialOption)
)
Contoh berikut menunjukkan permintaan OpenId4Vp1. Untuk mengetahui detail tentang kolom dalam permintaan ini, lihat dokumentasi OpenID.
{
"requests": [
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "OD8eP8BYfr0zyhgq4QCVEGN3m7C1Ht_No9H5fG5KJFk",
"dcql_query": {
"credentials": [
{
"id": "cred1",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"family_name"
]
},
{
"path": [
"org.iso.18013.5.1",
"given_name"
]
},
{
"path": [
"org.iso.18013.5.1",
"age_over_21"
]
}
]
}
]
}
}
}
]
}
Mendapatkan kredensial
Luncurkan alur getCredential dengan permintaan yang dibuat. Anda akan menerima
GetCredentialResponse yang berhasil, atau GetCredentialException jika
permintaan gagal.
Alur getCredential memicu dialog sistem Android untuk menampilkan opsi kredensial yang tersedia bagi pengguna dan mengumpulkan pilihan mereka. Selanjutnya, aplikasi dompet
yang berisi opsi kredensial yang dipilih akan menampilkan UI untuk mengumpulkan izin
dan melakukan tindakan yang diperlukan untuk menghasilkan respons kredensial digital.
coroutineScope.launch {
try {
val result = credentialManager.getCredential(
context = activityContext,
request = getCredRequest
)
verifyResult(result)
} catch (e : GetCredentialException) {
handleFailure(e)
}
}
// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
val credential = result.credential
when (credential) {
is DigitalCredential -> {
val responseJson = credential.credentialJson
validateResponseOnServer(responseJson)
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential ${credential.type}")
}
}
}
// Handle failure.
fun handleFailure(e: GetCredentialException) {
when (e) {
is GetCredentialCancellationException -> {
// The user intentionally canceled the operation and chose not
// to share the credential.
}
is GetCredentialInterruptedException -> {
// Retry-able error. Consider retrying the call.
}
is NoCredentialException -> {
// No credential was available.
}
else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
}
}
Permintaan multi-kredensial yang fleksibel
Digital Credentials API juga mendukung permintaan beberapa jenis kredensial sekaligus menggunakan OpenID4VP:
- Permintaan simultan: Meminta beberapa kredensial dalam satu transaksi pengguna. Misalnya, aplikasi perjalanan dapat meminta boarding pass dan tanda pengenal terbitan pemerintah secara bersamaan, sehingga pengguna dapat meninjau dan menyetujui keduanya dalam sekali ketuk.
- Pemenuhan fleksibel: Menerima salah satu dari beberapa jenis kredensial atau penerbit. Misalnya, alur verifikasi usia dapat menerima surat izin mengemudi atau paspor, sehingga pengguna dapat memenuhi permintaan menggunakan kredensial apa pun yang mereka simpan di pemegang kredensial.
Berikut adalah contoh permintaan beberapa kredensial dalam satu permintaan:
{
"credentials": [
{
"id": "gov_id1",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"age_over_21"
]
}
]
},
{
"id": "boarding_pass1",
"format": "dc+sd-jwt",
"meta": {
"vct_values": [
"https://credentials.example.airline/boarding-pass"
]
},
"claims": [
{
"path": [
"flight_number"
]
},
{
"path": [
"seat"
]
}
]
}
]
}
Menangani respons
Setelah membuat permintaan kredensial, tangani GetCredentialResponse
yang ditampilkan dari CredentialManager.
// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
val credential = result.credential
when (credential) {
is DigitalCredential -> {
val responseJson = credential.credentialJson
validateResponseOnServer(responseJson)
}
else -> {
// Catch any unrecognized credential type here.
Log.e(TAG, "Unexpected type of credential ${credential.type}")
}
}
}
Menangani pengecualian
Aplikasi Anda harus menangani error yang dapat ditampilkan, termasuk jika tidak ada kredensial di perangkat atau jika pengguna membatalkan operasi:
// Handle failure.
fun handleFailure(e: GetCredentialException) {
when (e) {
is GetCredentialCancellationException -> {
// The user intentionally canceled the operation and chose not
// to share the credential.
}
is GetCredentialInterruptedException -> {
// Retry-able error. Consider retrying the call.
}
is NoCredentialException -> {
// No credential was available.
}
is CreateCredentialUnknownException -> {
// An unknown, usually unexpected, error has occurred. Check the
// message error for any additional debugging information.
}
is CreateCredentialCustomException -> {
// You have encountered a custom error thrown by the wallet.
// If you made the API call with a request object that's a
// subclass of CreateCustomCredentialRequest using a 3rd-party SDK,
// then you should check for any custom exception type constants
// within that SDK to match with e.type. Otherwise, drop or log the
// exception.
}
else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
}
}