تنفيذ ميزة "استعادة بيانات الاعتماد" باستخدام "مدير بيانات الاعتماد"

توضّح هذه الصفحة كيفية إنشاء مفتاح استعادة وتسجيل الدخول باستخدامه وحذفه.

التوافق مع الإصدارات

تعمل ميزة "استعادة بيانات الاعتماد" في Credential Manager على الأجهزة التي تعمل بالإصدار 9 من نظام التشغيل Android والإصدارات الأحدث، والإصدار الأساسي 24220000 أو الإصدارات الأحدث من "خدمات Google Play" (GMS)، والإصدار 1.5.0 أو الإصدارات الأحدث من مكتبة androidx.credentials.

المتطلبات الأساسية

إعداد خادم معتمِد مشابه للخادم المستخدَم في مفاتيح المرور إذا سبق لك إعداد خادم للتعامل مع المصادقة باستخدام مفاتيح المرور، استخدِم عملية التنفيذ نفسها من جهة الخادم لاستعادة المفاتيح.

الطلبات التابعة

أضِف الاعتماديات التالية إلى ملف build.gradle الخاص بوحدة تطبيقك:

Kotlin

dependencies {
    implementation("androidx.credentials:credentials:1.7.0-alpha02")
    implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha02")
}

Groovy

dependencies {
    implementation "androidx.credentials:credentials:1.7.0-alpha02"
    implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha02"
}

تتوفّر ميزة "استعادة بيانات الاعتماد" من الإصدار 1.5.0 والإصدارات الأحدث من مكتبة androidx.credentials. ومع ذلك، يُنصح باستخدام أحدث الإصدارات الثابتة من التبعيات حيثما أمكن ذلك.

نظرة عامة

  1. إنشاء مفتاح استعادة: لإنشاء مفتاح استعادة، أكمِل الخطوات التالية:
    1. إنشاء مثيل لـ Credential Manager: أنشئ عنصر CredentialManager
    2. الحصول على خيارات إنشاء بيانات الاعتماد من خادم التطبيق: أرسِل إلى تطبيق العميل التفاصيل المطلوبة لإنشاء مفتاح الاستعادة من خادم تطبيقك.
    3. إنشاء مفتاح استعادة: أنشئ مفتاح استعادة لحساب المستخدم إذا كان المستخدم مسجّلاً الدخول إلى تطبيقك.
    4. التعامل مع ردّ إنشاء بيانات الاعتماد: أرسِل بيانات الاعتماد من تطبيق العميل إلى خادم تطبيقك لمعالجتها، وتعامل مع أي استثناءات.
  2. تسجيل الدخول باستخدام مفتاح استرداد: لتسجيل الدخول باستخدام مفتاح استرداد، أكمِل الخطوات التالية:
    1. الحصول على خيارات استرداد بيانات الاعتماد من خادم التطبيق: أرسِل إلى تطبيق العميل التفاصيل المطلوبة لاسترداد مفتاح النسخ الاحتياطي من خادم تطبيقك.
    2. الحصول على مفتاح الاستعادة: اطلب مفتاح الاستعادة من "مدير الاعتماد" عندما يضبط المستخدم جهازًا جديدًا. ويتيح ذلك للمستخدم تسجيل الدخول بدون الحاجة إلى إدخال أي بيانات إضافية.
    3. التعامل مع استجابة استرداد بيانات الاعتماد: أرسِل مفتاح الاستعادة من تطبيق العميل إلى خادم التطبيق لتسجيل دخول المستخدم.
  3. حذف مفتاح استعادة

إنشاء مفتاح استعادة

يجب أن يغطي تطبيقك جميع حالات تسجيل دخول المستخدم لضمان إنشاء مفتاح استعادة للمستخدمين النشطين. أنشئ مفتاح استعادة في السيناريوهات التالية:

  • إذا سجّل المستخدم دخوله ولم يتم إنشاء مفتاح استعادة بعد (كما هو الحال في الطريقة onCreate للسمة الرئيسية Activity).
  • عندما يسجّل المستخدم الدخول أو يُكمل إجراءات تسجيل حساب جديد

لتحسين الأداء وتجنُّب عبء إنشاء بيانات اعتماد استعادة أو التحقّق منها في كل عملية تسجيل دخول، اضبط العلامة boolean أو الطابع الزمني لإنشاء بيانات الاعتماد في وحدة التخزين المحلية، مثل has_synced_restore_credential، لتتبُّع ما إذا تم إنشاء المفتاح من قبل.

إنشاء مثيل لـ Credential Manager

استخدِم سياق نشاط تطبيقك لإنشاء عنصر CredentialManager.

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)

الحصول على خيارات إنشاء بيانات الاعتماد من خادم تطبيقك

استخدِم مكتبة متوافقة مع معيار FIDO في خادم تطبيقك لإرسال المعلومات المطلوبة إلى تطبيق العميل لإنشاء بيانات اعتماد الاستعادة، مثل معلومات عن المستخدم والتطبيق وخصائص الإعداد الإضافية. لمزيد من المعلومات حول عملية التنفيذ من جهة الخادم، اطّلِع على إرشادات حول التنفيذ من جهة الخادم.

إنشاء مفتاح الاستعادة

بعد تحليل خيارات إنشاء المفتاح العام التي أرسلها الخادم، أنشئ مفتاح استعادة من خلال تضمين هذه الخيارات في عنصر CreateRestoreCredentialRequest واستدعاء الطريقة createCredential() باستخدام العنصر CredentialManager.

// createRestoreRequest contains the details sent by the server 
val response = credentialManager.createCredential(context, createRestoreRequest)

نقاط أساسية حول الرمز

  • يحتوي العنصر CreateRestoreCredentialRequest على الحقول التالية:

    • requestJson: خيارات إنشاء بيانات الاعتماد التي يرسلها خادم التطبيق بتنسيق Web Authentication API من أجل PublicKeyCredentialCreationOptionsJSON.
    • isCloudBackupEnabled: حقل Boolean لتحديد ما إذا كان سيتم الاحتفاظ بنسخة احتياطية من مفتاح الاستعادة على السحابة الإلكترونية. تكون هذه العلامة مضبوطة تلقائيًا على true. يحتوي هذا الحقل على القيم التالية:

      • true: (يُنصح به) تتيح هذه القيمة الاحتفاظ بنسخة احتياطية من مفاتيح الاستعادة على السحابة الإلكترونية إذا كان المستخدم قد فعّل خدمة "الاحتفاظ بنسخة احتياطية" من Google والتشفير التام، مثل قفل الشاشة.
      • false: تحفظ هذه القيمة المفتاح محليًا وليس على السحابة الإلكترونية. لن يتوفّر المفتاح على الجهاز الجديد إذا اختار المستخدم إجراء عملية استعادة من السحابة الإلكترونية.

التعامل مع ردّ إنشاء بيانات الاعتماد

تعرض Credential Manager API ردًا من النوع CreateRestoreCredentialResponse. تحتوي هذه الاستجابة على استجابة تسجيل بيانات الاعتماد الخاصة بالمفتاح العام بتنسيق JSON.

أرسِل المفتاح العام من تطبيقك إلى خادم الجهة المعتمِدة. يشبه هذا المفتاح العام المفتاح العام الذي يتم إنشاؤه عند إنشاء مفتاح مرور. يمكن للرمز نفسه الذي يتعامل مع إنشاء مفتاح المرور على الخادم أن يتعامل أيضًا مع إنشاء مفتاح الاستعادة. لمزيد من المعلومات حول التنفيذ من جهة الخادم، يمكنك الاطّلاع على الإرشادات الخاصة بمفاتيح المرور.

أثناء عملية إنشاء مفتاح الاستعادة، تعامَل مع الاستثناءات التالية:

  • CreateRestoreCredentialDomException: يحدث هذا الاستثناء إذا كانت قيمة requestJson غير صالحة ولا تتّبع تنسيق WebAuthn الخاص بـ PublicKeyCredentialCreationOptionsJSON.
  • E2eeUnavailableException: يحدث هذا الاستثناء إذا كانت قيمة isCloudBackupEnabled هي true، ولكن جهاز المستخدم لا يتضمّن ميزة الاحتفاظ بنسخة احتياطية من البيانات أو التشفير التام بين الأطراف، مثل قفل الشاشة.
    لضمان إنشاء بيانات اعتماد الاسترداد في جميع الحالات، عليك التعامل مع E2eeUnavailableException بشكلٍ صريح من خلال استدعاء createCredential مع ضبط isCloudBackupEnabled على true. إذا تم عرض الخطأ E2eeUnavailableException، يجب تسجيله واستدعاء createCredential مرة أخرى مع ضبط isCloudBackupEnabled على false.
  • IllegalArgumentException: يحدث هذا الاستثناء إذا كان createRestoreRequest فارغًا أو بتنسيق JSON غير صالح، أو إذا لم يكن يتضمّن user.id صالحًا يتوافق مع مواصفات WebAuthn.

تسجيل الدخول باستخدام مفتاح استعادة

استخدِم ميزة "استعادة بيانات الاعتماد" لتسجيل دخول المستخدم بدون أي إجراء من جانبه أثناء عملية إعداد الجهاز.

الحصول على خيارات استرداد بيانات الاعتماد من خادم التطبيق

أرسِل إلى تطبيق العميل الخيارات المطلوبة للحصول على مفتاح الاستعادة من الخادم. للحصول على إرشادات مشابهة حول مفتاح المرور لهذه الخطوة، يُرجى الاطّلاع على مقالة تسجيل الدخول باستخدام مفتاح مرور. لمزيد من المعلومات عن عملية التنفيذ من جهة الخادم، يُرجى الاطّلاع على دليل المصادقة من جهة الخادم.

الحصول على مفتاح الاستعادة

للحصول على مفتاح الاستعادة على الجهاز الجديد، استدعِ الدالة getCredential() على العنصر CredentialManager.

يُنصح باسترداد مفتاح الاستعادة في كلتا الحالتَين التاليتَين:

  • عند تشغيل التطبيق لأول مرة على الجهاز لا تعتمد استعادة بيانات الاعتماد في هذه الحالة على استعادة بيانات التطبيق.
  • في حال تفعيل ميزة الاحتفاظ بنسخة احتياطية من بيانات التطبيقات واستعادتها، احصل على مفتاح الاستعادة فور استعادة بيانات التطبيقات. استخدِم BackupAgent لضبط إعدادات الاحتفاظ بنسخة احتياطية من تطبيقك، وتأكَّد من إكمال وظيفة getCredential ضمن معاودة الاتصال onRestoreFinished. لا تستخدِم طريقة onRestore، لأنّه يتم استدعاؤها فقط لعمليات النسخ الاحتياطي لمفاتيح القيمة، بينما يتم استدعاء onRestoreFinished بشكل موثوق لأي نوع من عمليات استعادة النسخ الاحتياطي. ويؤدي ذلك إلى تجنُّب أي تأخير محتمل عندما يفتح المستخدمون أجهزتهم الجديدة للمرة الأولى، كما يتيح لهم التفاعل مع التطبيق بدون انتظارهم لفتحه. على سبيل المثال، يتيح ذلك لتطبيقك إرسال إشعارات إلى المستخدم قبل أن يفتح التطبيق للمرة الأولى على الجهاز الجديد، وهو أمر مهم بشكل خاص لتطبيقات المراسلة أو الاتصالات.
// Fetch the options required to get the restore key
val authenticationJson = fetchAuthenticationJson()

// Create the GetRestoreCredentialRequest object
val options = GetRestoreCredentialOption(authenticationJson)
val getRequest = GetCredentialRequest(listOf(options))

val response = credentialManager.getCredential(context, getRequest)

// Type-check and extract the restore credential
val credential = response.credential as RestoreCredential

تعرض واجهات برمجة التطبيقات الخاصة بأداة إدارة بيانات الاعتماد ردًا من النوع GetCredentialResponse. إنّ بيانات الاعتماد الواردة في هذه الاستجابة هي من النوع RestoreCredential بشكل صريح، وهي تحتوي على المفتاح العام.

التعامل مع استجابة تسجيل الدخول

أرسِل المفتاح العام من التطبيق إلى خادم الجهة المعتمِدة، والذي يمكن استخدامه بعد ذلك لتسجيل دخول المستخدم. من جهة الخادم، يشبه هذا الإجراء عملية تسجيل الدخول باستخدام مفتاح مرور. يمكن للرمز نفسه الذي يتعامل مع تسجيل الدخول باستخدام مفاتيح المرور على الخادم أن يتعامل أيضًا مع عمليات تسجيل الدخول باستخدام مفاتيح الاسترداد. لمزيد من المعلومات حول عملية التنفيذ من جهة الخادم لمفاتيح المرور، يُرجى الاطّلاع على تسجيل الدخول باستخدام مفتاح مرور.

حذف مفتاح الاستعادة

لا يحتفظ "Credential Manager" بأي حالة ولا يدرك نشاط المستخدم، لذا لا يحذف مفاتيح الاستعادة تلقائيًا بعد استخدامها. لحذف مفتاح استعادة، استدعِ طريقة clearCredentialState(). لأغراض الأمان، احذف المفتاح عندما يسجّل المستخدم الخروج. يضمن ذلك أنّه في المرة التالية التي يفتح فيها المستخدم التطبيق على الجهاز نفسه، سيتم تسجيل خروجه وسيُطلب منه تسجيل الدخول مرة أخرى.

يُفسَّر إلغاء تثبيت تطبيق على أنّه إشارة إلى نية حذف مفتاح الاحتفاظ بنسخة احتياطية المقابل من هذا الجهاز، على غرار نية المستخدم عند تسجيل الخروج.

تتم إزالة مفاتيح الاستعادة في الحالات التالية فقط:

  • الإجراءات على مستوى النظام: إلغاء المستخدمين تثبيت التطبيق أو محو بياناته
  • عمليات استدعاء على مستوى التطبيق: احذف المفتاح آليًا من خلال استدعاء clearCredentialState() عند معالجة تسجيل خروج المستخدم في رمز تطبيقك.

عندما يسجّل المستخدم خروجه من تطبيقك، استدعِ طريقة clearCredentialState() على عنصر CredentialManager.

// Create a ClearCredentialStateRequest object
val clearRequest = ClearCredentialStateRequest(TYPE_CLEAR_RESTORE_CREDENTIAL)

// When the user logs out, delete the restore key
val response = credentialManager.clearCredentialState(clearRequest)