1. قبل البدء
تشكِّل حلول المصادقة التقليدية عددًا من التحديات المتعلقة بالأمان وسهولة الاستخدام.
يتم استخدام كلمات المرور على نطاق واسع، ولكن...
- سهولة نسيانها
- يحتاج المستخدمون إلى المعرفة اللازمة لإنشاء كلمات مرور قوية.
- يمكنك بسهولة صيد المهاجمين وحصادهم وإعادة اللعب.
عمِل Android على إنشاء Credential Manager API لتسهيل عملية تسجيل الدخول ومعالجة المخاطر الأمنية من خلال إتاحة مفاتيح المرور، وهي المعيار المتّبع في المجال من أجل المصادقة بدون كلمات مرور.
يجمع "مدير بيانات الاعتماد" بين إمكانية استخدام مفاتيح المرور وطُرق المصادقة التقليدية، مثل كلمات المرور وميزة "تسجيل الدخول باستخدام حساب Google" وغير ذلك.
سيتمكّن المستخدمون من إنشاء مفاتيح مرور وتخزينها في "مدير كلمات المرور في Google"، ما يؤدي إلى مزامنة مفاتيح المرور على أجهزة Android التي سجّل المستخدم الدخول عليها. يجب إنشاء مفتاح مرور وربطه بحساب مستخدم، وتخزين مفتاحه العام على خادم قبل أن يتمكّن المستخدم من تسجيل الدخول باستخدامه.
في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية الاشتراك باستخدام مفاتيح المرور وكلمة المرور من خلال واجهة برمجة تطبيقات Credential Manager API واستخدامها لأغراض المصادقة المستقبلية. هناك مساران، بما في ذلك:
- الاشتراك : باستخدام مفاتيح المرور وكلمة المرور.
- تسجيل الدخول : باستخدام مفاتيح المرور & كلمة مرور محفوظة.
المتطلبات الأساسية
- فهم أساسي لكيفية تشغيل التطبيقات في "استوديو Android"
- فهم أساسي لخطوات المصادقة في تطبيقات Android.
- فهم أساسي لمفاتيح المرور.
ما ستتعرَّف عليه
- كيفية إنشاء مفتاح مرور
- كيفية حفظ كلمة المرور في مدير كلمات المرور
- كيفية مصادقة المستخدمين باستخدام مفتاح مرور أو كلمة مرور محفوظة
المتطلبات
إحدى مجموعات الأجهزة التالية:
- جهاز Android يعمل بالإصدار 9 من نظام التشغيل Android أو إصدار أحدث (لمفاتيح المرور) والإصدار 4.4 من Android أو إصدار أحدث(لمصادقة كلمة المرور من خلال واجهة برمجة تطبيقات "إدارة بيانات الاعتماد")
- يُفضَّل أن يكون الجهاز مزوّدًا بأداة استشعار حيوية.
- احرص على تسجيل أحد المقاييس الحيوية (أو قفل الشاشة).
- إصدار المكون الإضافي لـ Kotlin : 1.8.10
2. الإعداد
- استنسِخ هذا المستودع على الكمبيوتر المحمول من فرع credman_codelab : https://github.com/android/identity-samples/tree/credman_codelab
- انتقِل إلى وحدة CredentialManager وافتح المشروع في "استوديو Android".
السماح بالاطّلاع على الحالة الأولية للتطبيق
لمعرفة طريقة عمل الحالة الأولية للتطبيق، اتبع الخطوات التالية:
- افتح التطبيق.
- ستظهر شاشة رئيسية تحتوي على زر "الاشتراك" و"تسجيل الدخول".
- يمكنك النقر على "اشتراك" للاشتراك باستخدام مفتاح مرور أو كلمة مرور.
- يمكنك النقر على "تسجيل الدخول" لتسجيل الدخول باستخدام مفتاح المرور كلمة مرور محفوظة.
للتعرّف على مفاتيح المرور وآلية عملها، يمكنك الاطّلاع على المقالة كيف تعمل مفاتيح المرور؟ .
3- إضافة إمكانية الاشتراك باستخدام مفاتيح المرور
عند الاشتراك للحصول على حساب جديد على أحد تطبيقات Android التي تستخدم واجهة برمجة تطبيقات Credential Manager، يمكن للمستخدمين إنشاء مفتاح مرور لحساباتهم. سيتم تخزين مفتاح المرور هذا بأمان في موفِّر بيانات الاعتماد الذي اختاره المستخدم، وسيتم استخدامه في عمليات تسجيل الدخول المستقبلية بدون أن يُطلب من المستخدم إدخال كلمة المرور في كل مرة.
والآن، ستقوم بإنشاء مفتاح مرور وتسجيل بيانات اعتماد المستخدم باستخدام المقاييس الحيوية/قفل الشاشة.
الاشتراك باستخدام مفتاح المرور
داخل مدير بيانات الاعتماد -> app -> الرئيسي -> java -> SignUpFragment.kt، يمكنك رؤية حقل النص "username" وزرًا للاشتراك باستخدام مفتاح المرور
اجتياز التحدي واستجابة json الأخرى لاستدعاء createPasskey()
قبل إنشاء مفتاح مرور، يجب أن تطلب من الخادم الحصول على المعلومات اللازمة لتمريرها إلى واجهة برمجة تطبيقات Credential Manager أثناء استدعاء createCredential() .
لحسن الحظ، لديك بالفعل استجابة وهمية في مواد العرض(RegFromServer.txt) تعرض مثل هذه المعلمات في هذا الدرس التطبيقي حول الترميز.
- في تطبيقك، انتقِل إلى طريقة SignUpFragment.kt و"Find" وsignUpWithPasskeys التي ستكتب فيها منطق إنشاء مفتاح مرور والسماح للمستخدم بالدخول إليه. يمكنك العثور على الطريقة في نفس الفئة.
- تحقق من القالب الآخر بتعليق لاستدعاء createPasskey() واستبداله بالرمز التالي :
SignUpFragment.kt
//TODO : Call createPasskey() to signup with passkey
val data = createPasskey()
سيتم استدعاء هذه الطريقة بمجرد ملء اسم مستخدم صالح على الشاشة.
- ضمن طريقة createPasskey() ، تحتاج إلى إنشاء CreatePublicKeyCredentialRequest() مع عرض المعلَمات الضرورية.
SignUpFragment.kt
//TODO create a CreatePublicKeyCredentialRequest() with necessary registration json from server
val request = CreatePublicKeyCredentialRequest(fetchRegistrationJsonFromServer())
إنّ طريقة purchaseJsonFromServer() هذه هي طريقة تقرأ استجابة ملف json للتسجيل من مواد العرض وتعرض ملف json للتسجيل الذي سيتم تمريره أثناء إنشاء مفتاح المرور.
- ابحث عن طريقة browseJsonFromServer() واستبدِل قائمة المهام بالتعليمة البرمجية التالية لعرض json وكذلك إزالة عبارة عرض السلسلة الفارغة :
SignUpFragment.kt
//TODO fetch registration mock response
val response = requireContext().readFromAsset("RegFromServer")
//Update userId,challenge, name and Display name in the mock
return response.replace("<userId>", getEncodedUserId())
.replace("<userName>", binding.username.text.toString())
.replace("<userDisplayName>", binding.username.text.toString())
.replace("<challenge>", getEncodedChallenge())
- هنا، يمكنك قراءة ملف json للتسجيل من مواد العرض.
- يتضمّن ملف json هذا 4 حقول سيتم استبدالها.
- يجب أن يكون رقم تعريف المستخدم فريدًا حتى يتمكّن المستخدم من إنشاء مفاتيح مرور متعددة (إذا لزم الأمر). تستبدل <userId> مع إنشاء رقم تعريف المستخدم.
- <challenge> يجب أيضًا أن يكون فريدًا؛ لذا ستنشئ تحديًا فريدًا عشوائيًا. سبق أن أضفت الطريقة إلى الرمز الخاص بك.
يتضمن مقتطف الرمز التالي نماذج الخيارات التي تتلقاها من الخادم:
{
"challenge": String,
"rp": {
"name": String,
"id": String
},
"user": {
"id": String,
"name": String,
"displayName": String
},
"pubKeyCredParams": [
{
"type": "public-key",
"alg": -7
},
{
"type": "public-key",
"alg": -257
}
],
"timeout": 1800000,
"attestation": "none",
"excludeCredentials": [],
"authenticatorSelection": {
"authenticatorAttachment": "platform",
"requireResidentKey": true,
"residentKey": "required",
"userVerification": "required"
}
}
الجدول التالي ليس شاملاً، ولكنه يحتوي على المعلَمات المهمة في قاموس PublicKeyCredentialCreationOptions
:
المعلّمات | الأوصاف |
سلسلة عشوائية ينشئها الخادم تحتوي على قصور كافٍ بما يجعل تخمينها غير ممكن. يجب ألا يقل طوله عن 16 بايت. هذا الإجراء مطلوب ولكن لا يتم استخدامه أثناء التسجيل ما لم يتم تقديم مصادقة. | |
المعرّف الفريد للمستخدم ويجب ألا تتضمّن هذه القيمة معلومات تحديد الهوية الشخصية، مثل عناوين البريد الإلكتروني أو أسماء المستخدمين. لذا فإن القيمة العشوائية 16 بايت التي يتم إنشاؤها لكل حساب ستكون مناسبة. | |
يجب أن يتضمّن هذا الحقل معرّفًا فريدًا للحساب الذي سيتعرّف عليه المستخدم، مثل عنوان بريده الإلكتروني أو اسم المستخدم. وسيتمّ عرض هذا الاسم في أداة اختيار الحسابات. (في حال استخدام اسم مستخدم، يُرجى استخدام القيمة نفسها الواردة في مصادقة كلمة المرور). | |
هذا الحقل هو اسم اختياري للحساب يسهل استخدامه بشكلٍ أكبر. إنه اسم جذاب لحساب المستخدم، وهو مخصّص للعرض فقط. | |
يتوافق "كيان الطرف المعتمد" مع تفاصيل طلبك، ويحتاج إلى :
| |
معلمات اعتماد المفتاح العام هي قائمة من الخوارزميات وأنواع المفاتيح المسموح بها. يجب أن تحتوي هذه القائمة على عنصر واحد على الأقل. | |
قد يكون المستخدم الذي يحاول تسجيل جهاز قد سجّل أجهزة أخرى. للحد من إنشاء بيانات اعتماد متعددة للحساب نفسه على أداة مصادقة واحدة، يمكنك تجاهل هذه الأجهزة. يجب أن يحتوي العنصر transports، في حال توفّره، على نتيجة استدعاء getTransports() أثناء تسجيل كل بيانات اعتماد. | |
تشير إلى ما إذا كان يجب توصيل الجهاز بالنظام الأساسي أم لا أو ما إذا لم يكن هناك أي متطلبات بشأنه. اضبطه على "النظام الأساسي". يشير هذا إلى أننا بحاجة إلى برنامج مصادقة مضمّن في جهاز النظام الأساسي، ولن يُطلب من المستخدم إدخال، مثلاً. مفتاح أمان USB. | |
| تشير إلى قيمة "مطلوبة" لإنشاء مفتاح مرور. |
إنشاء بيانات اعتماد
- بمجرد إنشاء CreatePublicKeyCredentialRequest()، عليك استدعاء استدعاء createCredential() بالطلب الذي تم إنشاؤه.
SignUpFragment.kt
//TODO call createCredential() with createPublicKeyCredentialRequest
try {
response = credentialManager.createCredential(
requireActivity(),
request
) as CreatePublicKeyCredentialResponse
} catch (e: CreateCredentialException) {
configureProgress(View.INVISIBLE)
handlePasskeyFailure(e)
}
- يمكنك تمرير المعلومات المطلوبة إلى createCredential().
- بعد نجاح الطلب، ستظهر لك بطاقة سفلية على الشاشة تطلب منك إنشاء مفتاح مرور.
- يمكن للمستخدمين الآن إثبات هويتهم من خلال المقاييس الحيوية أو قفل الشاشة وما إلى ذلك.
- ستتعامل مع إذن الوصول إلى طرق العرض المعروضة وتتعامل مع الاستثناءات في حال تعذُّر الطلب أو عدم نجاحه لسبب ما. هنا، يتم تسجيل رسائل الخطأ وعرضها على التطبيق في مربّع حوار الخطأ. يمكنك الاطّلاع على سجلّات الأخطاء الكاملة من خلال "استوديو Android" أو أمر تصحيح أخطاء adb.
- وأخيرًا، تحتاج الآن إلى إكمال عملية التسجيل عن طريق إرسال بيانات اعتماد المفتاح العام إلى الخادم والسماح للمستخدم بالدخول. يتلقّى التطبيق عنصر بيانات اعتماد يحتوي على مفتاح عام يمكنك إرساله إلى الخادم لتسجيل مفتاح المرور.
لقد استخدمنا هنا خادمًا وهميًا، لذا فإننا نعرض فقط القيمة "true" للإشارة إلى أن الخادم قد حفظ المفتاح العام المسجل لأغراض المصادقة والتحقق في المستقبل.
داخل طريقة signUpWithPasskeys()، ابحث عن التعليق ذي الصلة واستبدله بالتعليمة البرمجية التالية:
SignUpFragment.kt
//TODO : complete the registration process after sending public key credential to your server and let the user in
data?.let {
registerResponse()
DataProvider.setSignedInThroughPasskeys(true)
listener.showHome()
}
- تُرجع القيمة "RegisterResponse" القيمة "صحيح" إلى أنّ الخادم (التجريبي) قد حفظ المفتاح العام لاستخدامه في المستقبل.
- لقد ضبطت علامة SignedInThroughPasskeys على أنّها "صحيحة"، ما يشير إلى أنّك تسجّل الدخول باستخدام مفاتيح المرور.
- بعد تسجيل الدخول، تتم إعادة توجيه المستخدم إلى الشاشة الرئيسية.
يتضمن مقتطف الرمز التالي أمثلة على الخيارات التي ينبغي لك الحصول عليها:
{
"id": String,
"rawId": String,
"type": "public-key",
"response": {
"clientDataJSON": String,
"attestationObject": String,
}
}
الجدول التالي ليس شاملًا، ولكنّه يحتوي على المَعلمات المهمة في PublicKeyCredential
:
المعلّمات | الأوصاف |
رقم تعريف Base64URL مرمّز لمفتاح المرور الذي تم إنشاؤه. يساعد رقم التعريف هذا المتصفّح في تحديد ما إذا كان هناك مفتاح مرور مطابق متوفّر في الجهاز عند إجراء المصادقة. يجب تخزين هذه القيمة في قاعدة البيانات على الواجهة الخلفية. | |
إصدار عنصر | |
عنصر | |
عنصر مصادقة مشفّر بتنسيق |
شغّل التطبيق، وستتمكن من النقر على الزر "التسجيل باستخدام مفاتيح المرور" وإنشاء مفتاح مرور.
4. حفظ كلمة المرور في "مزوّد بيانات الاعتماد"
في هذا التطبيق، وداخل شاشة SignUp، لديك بالفعل اشتراك باستخدام اسم المستخدم وكلمة المرور الذين تم تنفيذهما لأغراض التوضيح.
لحفظ بيانات اعتماد كلمة مرور المستخدم لدى موفر كلمة المرور، ستقوم بتنفيذ CreatePasswordRequest لتمرير إلى createCredential() لحفظ كلمة المرور.
- ابحث عن طريقة signUpWithPassword() ، واستبدِل قائمة المهام لاستدعاء createPassword :
SignUpFragment.kt
//TODO : Save the user credential password with their password provider
createPassword()
- في طريقة createPassword()، تحتاج إلى إنشاء طلب كلمة مرور مثل هذا، واستبدل قائمة المهام بالرمز التالي :
SignUpFragment.kt
//TODO : CreatePasswordRequest with entered username and password
val request = CreatePasswordRequest(
binding.username.text.toString(),
binding.password.text.toString()
)
- بعد ذلك، في طريقة createPassword()، ستحتاج إلى إنشاء بيانات اعتماد من خلال إنشاء طلب كلمة مرور وحفظ بيانات اعتماد كلمة مرور المستخدم لدى موفر كلمة المرور الخاص به، واستبدال قائمة المهام بالرمز التالي :
SignUpFragment.kt
//TODO : Create credential with created password request
try {
credentialManager.createCredential(request, requireActivity()) as CreatePasswordResponse
} catch (e: Exception) {
Log.e("Auth", " Exception Message : " + e.message)
}
- لقد نجحت الآن في حفظ بيانات اعتماد كلمة المرور لدى موفر كلمة مرور المستخدم للمصادقة عبر كلمة المرور بنقرة واحدة فقط.
5- إضافة إمكانية المصادقة باستخدام مفتاح مرور أو كلمة مرور
ويمكنك الآن استخدامها كطريقة للمصادقة في تطبيقك بأمان.
الحصول على التحدي والخيارات الأخرى لتمريره إلى استدعاء getPasskey()
قبل أن تطلب من المستخدم المصادقة، عليك طلب معلَمات لتمرير WebAuthn json من الخادم، بما في ذلك التحقّق.
لديك حاليًا استجابة وهمية في مواد العرض(AuthFromServer.txt) تعرض مثل هذه المَعلمات في هذا الدرس التطبيقي حول الترميز.
- في تطبيقك، انتقِل إلى SignInFragment.kt، وابحث عن طريقة
signInWithSavedCredentials
التي ستكتب فيها منطق المصادقة باستخدام مفتاح المرور المحفوظ أو كلمة المرور المحفوظة، ثم تسمح للمستخدم بالدخول إلى : - تحقق من القالب الآخر بتعليق لاستدعاء createPasskey() واستبداله بالرمز التالي :
SignInFragment.kt
//TODO : Call getSavedCredentials() method to signin using passkey/password
val data = getSavedCredentials()
- ضمن طريقة getSavedCredentials() ، عليك إنشاء
GetPublicKeyCredentialOption
() بالمعلَمات اللازمة للحصول على بيانات الاعتماد من موفِّر بيانات الاعتماد.
SigninFragment.kt
//TODO create a GetPublicKeyCredentialOption() with necessary registration json from server
val getPublicKeyCredentialOption =
GetPublicKeyCredentialOption(fetchAuthJsonFromServer(), null)
إنّ طريقة BringAuthJsonFromServer() هذه هي طريقة تقرأ استجابة ملف json للمصادقة من الأصول وتُرجع ملف json للمصادقة لاسترداد جميع مفاتيح المرور المرتبطة بحساب المستخدم هذا.
المعلمة الثانية : clientDataHash - وهي تجزئة تُستخدم لإثبات هوية الجهة المعتمدة، ولا يتم ضبطها إلا في حال ضبط GetCredentialRequest.origin. بالنسبة إلى نموذج التطبيق، لا توجد قيمة فارغة.
تكون المعلمة الثالثة true إذا كنت تفضل عرض العملية فورًا عند عدم وجود بيانات اعتماد متاحة بدلاً من الرجوع إلى اكتشاف بيانات الاعتماد عن بُعد، وخطأ (تلقائي) في الحالات الأخرى.
- ابحث عن طريقةFetchAuthJsonFromServer() واستبدال قائمة المهام بالرمز التالي لعرض json وكذلك إزالة عبارة إرجاع السلسلة الفارغة :
SignInFragment.kt
//TODO fetch authentication mock json
return requireContext().readFromAsset("AuthFromServer")
ملاحظة : تم تصميم خادم هذا الدرس التطبيقي لعرض ملف JSON مشابه قدر الإمكان لقاموس PublicKeyCredentialRequestOptions
الذي تم تمريره إلى استدعاء getCredential() لواجهة برمجة التطبيقات. يتضمن مقتطف الرمز التالي بعض الأمثلة على الخيارات التي ينبغي أن تتلقاها:
{
"challenge": String,
"rpId": String,
"userVerification": "",
"timeout": 1800000
}
الجدول التالي ليس شاملاً، ولكنه يحتوي على المعلَمات المهمة في قاموس PublicKeyCredentialRequestOptions
:
المعلّمات | الأوصاف |
تحدٍّ من إنشاء الخادم في عنصر | |
رقم تعريف الجهة المحظورة هو نطاق. يمكن أن يحدد الموقع الإلكتروني إما نطاقه أو لاحقة قابلة للتسجيل. يجب أن تتطابق هذه القيمة مع معلَمة |
- بعد ذلك، عليك إنشاء كائن كلمة المرور Option() لاسترداد جميع كلمات المرور المحفوظة المحفوظة في موفِّر كلمات المرور من خلال واجهة برمجة تطبيقات "مدير بيانات الاعتماد" لحساب المستخدم هذا. في طريقة getSavedCredentials()، ابحث عن قائمة المهام واستبدلها بما يلي :
SigninFragment.kt
//TODO create a PasswordOption to retrieve all the associated user's password
val getPasswordOption = GetPasswordOption()
الحصول على بيانات الاعتماد
- بعد ذلك، تحتاج إلى استدعاء طلب getCredential() بجميع الخيارات المذكورة أعلاه لاسترداد بيانات الاعتماد المرتبطة :
SignInFragment.kt
//TODO call getCredential() with required credential options
val result = try {
credentialManager.getCredential(
requireActivity(),
GetCredentialRequest(
listOf(
getPublicKeyCredentialOption,
getPasswordOption
)
)
)
} catch (e: Exception) {
configureViews(View.INVISIBLE, true)
Log.e("Auth", "getCredential failed with exception: " + e.message.toString())
activity?.showErrorAlert(
"An error occurred while authenticating through saved credentials. Check logs for additional details"
)
return null
}
if (result.credential is PublicKeyCredential) {
val cred = result.credential as PublicKeyCredential
DataProvider.setSignedInThroughPasskeys(true)
return "Passkey: ${cred.authenticationResponseJson}"
}
if (result.credential is PasswordCredential) {
val cred = result.credential as PasswordCredential
DataProvider.setSignedInThroughPasskeys(false)
return "Got Password - User:${cred.id} Password: ${cred.password}"
}
if (result.credential is CustomCredential) {
//If you are also using any external sign-in libraries, parse them here with the utility functions provided.
}
- يمكنك تمرير المعلومات المطلوبة إلى getCredential(). يؤدي ذلك إلى إضافة قائمة بخيارات بيانات الاعتماد وسياق النشاط لعرض الخيارات في البطاقة السفلية في هذا السياق.
- بعد نجاح الطلب، ستظهر لك بطاقة سفلية على الشاشة تسرد جميع بيانات الاعتماد التي تم إنشاؤها للحساب المرتبط.
- ويمكن للمستخدمين الآن إثبات هويتهم من خلال المقاييس الحيوية أو قفل الشاشة وما إلى ذلك لمصادقة بيانات الاعتماد التي تم اختيارها.
- لقد ضبطت علامة SignedInThroughPasskeys على أنّها "صحيحة"، ما يشير إلى أنّك تسجّل الدخول باستخدام مفاتيح المرور. وبخلاف ذلك، يتم عرض "خطأ".
- ستتعامل مع إذن الوصول إلى طرق العرض المعروضة وتتعامل مع الاستثناءات في حال تعذُّر الطلب أو عدم نجاحه لسبب ما. هنا، يتم تسجيل رسائل الخطأ وعرضها على التطبيق في مربّع حوار الخطأ. يمكنك الاطّلاع على سجلّات الأخطاء الكاملة من خلال "استوديو Android" أو أمر تصحيح أخطاء adb.
- وأخيرًا، تحتاج الآن إلى إكمال عملية التسجيل عن طريق إرسال بيانات اعتماد المفتاح العام إلى الخادم والسماح للمستخدم بالدخول. يتلقّى التطبيق عنصر بيانات اعتماد يحتوي على مفتاح عام يمكنك إرساله إلى الخادم للمصادقة عبر مفتاح المرور.
هنا، استخدمنا خادمًا وهميًا، لذا فإننا نعرض فقط true للإشارة إلى أن الخادم قد تحقق من صحة المفتاح العام.
داخل طريقة signInWithSavedCredentials
()، ابحث عن التعليق ذي الصلة واستبدله بالرمز التالي:
SignInFragment.kt
//TODO : complete the authentication process after validating the public key credential to your server and let the user in.
data?.let {
sendSignInResponseToServer()
listener.showHome()
}
- SendSigninResponseToServer() يعرض القيمة "صحيح" للإشارة إلى أنّ الخادم (mock) قد تحقّق من صحة المفتاح العام لاستخدامه في المستقبل.
- بعد تسجيل الدخول، تتم إعادة توجيه المستخدم إلى الشاشة الرئيسية.
يتضمّن مقتطف الرمز التالي مثالاً على عنصر PublicKeyCredential
:
{
"id": String
"rawId": String
"type": "public-key",
"response": {
"clientDataJSON": String
"authenticatorData": String
"signature": String
"userHandle": String
}
}
الجدول التالي ليس شاملًا، ولكنّه يحتوي على المَعلمات المهمة في العنصر PublicKeyCredential
:
المعلّمات | الأوصاف |
هذه السمة هي رقم تعريف Base64URL المشفر لبيانات اعتماد مفتاح المرور الذي تمت مصادقته. | |
إصدار عنصر | |
عنصر | |
عنصر | |
عنصر | |
عنصر |
شغّل التطبيق، وانتقل لتسجيل الدخول -> سجِّل الدخول باستخدام مفاتيح المرور أو كلمة المرور المحفوظة وحاوِل تسجيل الدخول باستخدام بيانات الاعتماد المحفوظة.
التجربة الآن
لقد نفّذت عملية إنشاء مفاتيح مرور، وتوفير كلمات المرور في "مدير بيانات الاعتماد"، والمصادقة من خلال مفاتيح المرور أو كلمات المرور المحفوظة باستخدام واجهة برمجة التطبيقات Credential Manager API في تطبيق Android.
6- تهانينا!
لقد أنهيت هذا الدرس التطبيقي حول الترميز. للاطّلاع على درجة الدقة النهائية، يمكنك الانتقال إلى https://github.com/android/identity-samples/tree/main/CredentialManager.
إذا كان لديك أي أسئلة، يمكنك طرحها على StackOverflow باستخدام علامة passkey
.