يمكن استخدام ميزة التحقّق من بيانات الاعتماد الرقمية داخل تطبيقات Android للمصادقة على هوية المستخدم (مثل مستند تعريف هوية صادر عن جهة حكومية) والتأكّد منها، أو التأكّد من خصائص المستخدم (مثل رخصة القيادة أو الشهادة الأكاديمية أو السمات مثل العمر أو العنوان)، أو في سيناريوهات أخرى تتطلّب إصدار بيانات اعتماد والتحقّق منها للتأكّد من صحة كيان معيّن.
"المستندات الرقمية" هي معيار W3C متاح للجميع يحدّد كيفية الوصول إلى المستندات الرقمية التي يمكن التحقّق منها من محفظة رقمية، ويتم تنفيذه لحالات الاستخدام على الويب باستخدام W3C Credential Management API. على أجهزة Android، يتم استخدام واجهة برمجة التطبيقات DigitalCredential في Credential Manager للتحقّق من صحة المستندات الرقمية.
التوافق مع إصدارات Android
تتوفّر واجهة برمجة التطبيقات Verifier API على الإصدار 9 من نظام التشغيل Android (المستوى 28 من واجهة برمجة التطبيقات) والإصدارات الأحدث.
التنفيذ
لإثبات صحة المستندات الرقمية في مشروع Android، اتّبِع الخطوات التالية:
- أضِف التبعيات إلى نص برمجة الإصدار في تطبيقك، ثم ابدأ في استخدام فئة
CredentialManager. - أنشئ طلب بيانات اعتماد رقمية واستخدِمه لتهيئة
DigitalCredentialOption، ثم أنشئGetCredentialRequest. - ابدأ مسار
getCredentialباستخدام الطلب الذي تم إنشاؤه لتلقّيGetCredentialResponseناجح أو معالجة أي استثناءات قد تحدث. بعد استرداد الردّ بنجاح، تحقَّق من صحته.
إضافة التبعيات وإعدادها
أضِف الاعتمادات التالية إلى نص برمجة إنشاء Gradle:
dependencies {
implementation("androidx.credentials:credentials:1.6.0-beta01")
implementation("androidx.credentials:credentials-play-services-auth:1.6.0-beta01")
}
بعد ذلك، ابدأ مثيلاً من الفئة CredentialManager.
val credentialManager = CredentialManager.create(context)
إنشاء طلب مستند تعريف رقمي
أنشئ طلب بيانات اعتماد رقمية واستخدِمه لتهيئة 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)
)
في ما يلي مثال على طلب OpenId4Vp. يمكنك الاطّلاع على المرجع الكامل على هذا الموقع الإلكتروني.
{
"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"
]
}
]
}
]
}
}
}
]
}
الحصول على بيانات الاعتماد
ابدأ مسار getCredential باستخدام الطلب الذي تم إنشاؤه. ستتلقّى إما GetCredentialResponse ناجحًا أو GetCredentialException في حال تعذّر تنفيذ الطلب.
يؤدي مسار getCredential إلى تشغيل مربّعات حوار نظام Android لعرض خيارات بيانات الاعتماد المتاحة للمستخدم وجمع اختياره. بعد ذلك، سيعرض تطبيق المحفظة الذي يتضمّن خيار المستند المحدّد واجهات مستخدم لجمع الموافقة وتنفيذ الإجراءات اللازمة لإنشاء ردّ بشأن المستند الرقمي.
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.
}
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}")
}
}