يوضّح هذا الدليل بالتفصيل كيفية استخدام DigitalCredential API للحصول على أرقام هواتف تم تأكيدها للمستخدمين. تتضمّن العملية خطوتَين:
- طلب
TS.43 token
: يطلب تطبيق العميل (الذي يُعرف باسم "المُدقّق") رمزًا مميّزًا مؤقتًا من TS.43 من جهاز المستخدم.TS.43 token
هي مستند تعريف صادر عن شركة الاتصالات ويمثّل هوية المستخدم. - استبدال الرمز المميز برقم هاتف: يستبدل الخلفية في تطبيقك الرمز المميز
TS.43 token
مع خدمة تجميع أو مشغّل شبكة جوّال للحصول على رقم هاتف المستخدم الذي تم إثبات ملكيته.
المتطلّبات الأساسية
لتنفيذ عملية إثبات ملكية رقم الهاتف باستخدام DigitalCredential API، يجب أن يكون لديك حساب لدى جهة تجميع. يتفاعل المجمّع مع شركات النقل ويوفّر مساحة واجهة برمجة التطبيقات اللازمة لتطبيقك، وعادةً ما يكون ذلك كنقطة نهاية لواجهة برمجة تطبيقات سحابية قابلة للفوترة.
عليك أيضًا إضافة التبعيات التالية إلى نص Gradle البرمجي:
Kotlin
dependencies { implementation("androidx.credentials:credentials:1.6.0-alpha05") implementation("androidx.credentials:credentials-play-services-auth:1.6.0-alpha05") }
Groovy
dependencies { implementation "androidx.credentials:credentials:1.6.0-alpha05" implementation "androidx.credentials:credentials-play-services-auth:1.6.0-alpha05" }
التنفيذ
تتّبع العملية الشاملة الخطوات التالية بشكل عام:
- طلب مَعلمات DCQL (لغة طلب البحث عن المستندات الرقمية) من جهة تجميع: اتّصِل بجهة تجميع واحدة أو أكثر واطلب مجموعة من مَعلمات DCQL. تتيح لك DCQL تحديد بيانات الاعتماد الرقمية المحدّدة التي تحتاج إليها من كل جهة تجميع.
إنشاء طلب OpenID4VP: من الخلفية في تطبيقك، أنشئ طلب OpenID4VP، مع تضمين مَعلمات DCQL من خدمة التجميع. بعد ذلك، أرسِل طلب OpenID4VP إلى تطبيق العميل.
طلب بيانات الاعتماد من خلال واجهة برمجة التطبيقات Credential Manager: في تطبيق العميل، استخدِم واجهة برمجة التطبيقات Credential Manager لإرسال طلب OpenID4VP إلى نظام التشغيل. في المقابل، ستتلقّى عنصر استجابة OpenID4VP يتضمّن
TS.43 Digital Credential
. يتم تشفير بيانات الاعتماد هذه ولا يمكن فك تشفيرها إلا من خلال خدمة التجميع المرتبطة بها. بعد تلقّي رمز شركة الاتصالات، أرسِل الردّ من تطبيق العميل إلى الخلفية الخاصة بالتطبيق.التحقّق من صحة الردّ: في الخلفية الخاصة بتطبيقك، تحقَّق من صحة الردّ الوارد من OpenID4VP.
الاستبدال برقم الهاتف: من الخلفية البرمجية لتطبيقك، أرسِل
TS.43 Digital Credential
إلى خدمة التجميع. يتحقّق موفّر خدمة التجميع من صحة بيانات الاعتماد ويعرض رقم الهاتف الذي تم تأكيده.
طلب مَعلمات DCQL من خدمة تجميع
من الخلفية البرمجية لتطبيقك، أرسِل طلبًا إلى خدمة التجميع للحصول على عنصر بيانات اعتماد Digital Credential Query Language (DCQL). احرص على تقديم قيمة عشوائية ورقم تعريف الطلب في طلبك. تعرض أداة التجميع عنصر بيانات اعتماد DCQL، الذي يتضمّن بنية مشابهة لما يلي:
{
// The credential ID is mapped to the request ID that is sent in your request to the aggregator.
"id": "aggregator1",
"format": "dc-authorization+sd-jwt",
"meta": {
"vct_values": [
"number-verification/device-phone-number/ts43"
],
"credential_authorization_jwt": "..."
},
"claims": [
{
"path": ["subscription_hint"],
"values": [1]
},
{
"path": ["phone_number_hint"],
"values": ["+14155552671"]
}
]
}
إنشاء طلب OpenID4VP
أولاً، من الخلفية البرمجية لتطبيقك، أنشئ عنصر dcql_query
من خلال وضع عنصر بيانات اعتماد DCQL في مصفوفة credentials
مضمّنة في عنصر dcql_query
كما هو موضّح في المثال التالي:
"dcql_query": {
"credentials": [
"id": "aggregator1",
"format": "dc-authorization+sd-jwt",
"meta": {
"vct_values": [
"number-verification/device-phone-number/ts43"
],
"credential_authorization_jwt": "..."
},
"claims": [
{
"path": ["subscription_hint"],
"values": [1]
},
{
"path": ["phone_number_hint"],
"values": ["+14155552671"]
}
]
]
}
بعد ذلك، أنشِئ طلب OpenID4VP بالبنية التالية:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
protocol
: يجب ضبطه علىopenid4vp-v1-unsigned
لطلبات التحقّق من رقم الهاتف.-
response_type
وresponse_mode
: ثوابت تشير إلى تنسيق الطلب بقيم ثابتةvp_token
وdc_api
على التوالي. nonce
: قيمة فريدة ينشئها الخلفية لكل طلب. يجب أن يتطابق الرقم العشوائي في عنصر بيانات اعتماد DCQL الخاص بالمجمّع مع هذا الرقم العشوائي.-
dcql_query
: في هذه الحالة، استخدِم السمةdcql_query
لتحديد أنّه يتم طلبTS.43 Digital Credential
. يمكنك أيضًا طلب مستندات اعتماد رقمية أخرى هنا.
بعد ذلك، عليك تضمين طلب OpenID4VP في عنصر طلب DigitalCredential API وإرساله إلى تطبيق العميل.
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
]
}
يوضّح المقتطف التالي كيفية إنشاء طلب DigitalCredential API:
def GenerateDCRequest():
credentials = []
aggregator1_dcql = call_aggregator_endpoint(nonce, "aggregator1", additional_params)
credentials.append(aggregator1_dcql) # You can optionally work with multiple
# aggregators, or request other types of credentials
val dc_request =
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": {"credentials": credentials}
}
}
]
}
return dc_request
استدعاء واجهة برمجة التطبيقات Credential Manager API
في تطبيق العميل، أرسِل طلبًا إلى Credential Manager API، مع طلب DigitalCredential API الذي يوفّره الخلفية في تطبيقك.
val requestJson = generateTs43DigitalCredentialRequestFromServer()
val digiCredOption = GetDigitalCredentialOption(requestJson = requestJson)
val getCredRequest = GetCredentialRequest(
listOf(digiCredOption)
)
coroutineScope.launch {
try {
val response = credentialManager.getCredential(
context = activityContext,
request = getCredRequest
)
val credential = response.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}")
}
}
} catch (e : GetCredentialException) {
// If user cancels the operation, the feature isn't available, or the
// SIM doesn't support the feature, a GetCredentialCancellationException
// will be returned. Otherwise, a GetCredentialUnsupportedException will
// be returned with details in the exception message.
handleFailure(e)
}
}
يتضمّن الردّ من DigitalCredential API الردّ من OpenID4VP. في ما يلي مثال على ملف JSON نموذجي خاص بشهادة اعتماد من نتيجة DigitalCredential
:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"vp_token": {
"aggregator1": ["eyJhbGciOiAiRVMy..."] # The encrypted TS.43 Digital
# Credential in an array structure.
}
}
}
من تطبيق العميل، أرسِل ردّ واجهة برمجة التطبيقات DigitalCredential إلى خادم الخلفية حيث يمكن التحقّق منه واستخدامه للحصول على رقم الهاتف الذي تم التحقّق منه من خلال خدمة تجميع.
التحقّق من صحة استجابة بيانات الاعتماد الرقمية
في ما يلي مثال على كيفية تحليل الردّ وتنفيذ خطوة التحقّق في الخلفية الخاصة بتطبيقك:
def processDigitalCredentialsResponse(response):
# Step 1: Parse out the TS.43 Digital Credential from the response
openId4VpResponse = response['data']
ts43_digital_credential = response['vp_token']["aggregator1"][0]
# Step 2: Perform response validation
verifyResponse(ts43_digital_credential)
def verifyResponse(ts43_digital_credential):
# The returned ts43_digital_credential is an SD-JWT-based Verifiable Credentials
# (SD-JWT VC) as defined in this IETF spec. The section 3.4 of the specification
# outlines how to validate the credential. At a high level, the steps involves
# validating (1) the nonce in the response credential matches the one in the
# request, (2) the integrity of the credential by checking the credential is
# signed by the trusted issuer Android Telephony, and (3) other validity
# properties associated with this credential, such as issue time and expiration
# time
# In most cases, you can use an SD-JWT VC library to perform these validations.
# Some aggregators may also perform the validation logic for you. Check with your
# aggregator to decide the exact scope of the validation required.
استبدال رقم الهاتف
من الخلفية البرمجية لتطبيقك، أرسِل TS.43 Digital Credential
الذي تم التحقّق منه إلى نقطة نهاية خدمة التجميع، وذلك للتحقّق من صحة بيانات الاعتماد وتلقّي رقم الهاتف الذي تم التحقّق منه.
def processDigitalCredentialsResponse(response):
# ... prior steps
# Step 3: Call aggregator endpoint to exchange the verified phone number
callAggregatorPnvEndpoint(ts43_digital_credential)