دمج "مدير بيانات الاعتماد" مع ميزة "تسجيل الدخول باستخدام حساب Google"

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

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

لإعداد ميزة "تسجيل الدخول باستخدام حساب Google"، اتّبِع الخطوتَين الأساسيتَين التاليتَين:

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

البطاقة السفلية لـ "مدير بيانات الاعتماد"
الشكل 1. واجهة المستخدم لاختيار بيانات اعتماد "مدير بيانات الاعتماد"

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

صورة متحركة تعرض عملية "تسجيل الدخول باستخدام حساب Google"
الشكل 2. واجهة المستخدم للزر "تسجيل الدخول باستخدام حساب Google"

يوضّح هذا المستند كيفية دمج زر "تسجيل الدخول باستخدام حساب Google" ومربّع الحوار السفلي مع واجهة برمجة تطبيقات "إدارة بيانات الاعتماد" باستخدام مكتبة المساعدة لرقم تعريف Google.

إعداد مشروع وحدة تحكُّم Google APIs

  1. افتح مشروعك في وحدة تحكم واجهة برمجة التطبيقات أو أنشِئ مشروعًا إذا لم يكن لديك مشروع.
  2. في صفحة شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth، تأكَّد من أنّ جميع المعلومات كاملة ودقيقة.
    1. يُرجى التأكّد من تحديد اسم التطبيق وشعاره والصفحة الرئيسية للتطبيق بشكل صحيح. سيتم عرض هذه القيم للمستخدمين في شاشة طلب الموافقة من خلال ميزة "تسجيل الدخول باستخدام حساب Google" عند الاشتراك وفي شاشة التطبيقات والخدمات التابعة لجهات خارجية.
    2. تأكّد من تحديد عناوين URL لسياسة الخصوصية وبنود الخدمة لتطبيقك.
  3. في صفحة "بيانات الاعتماد"، أنشئ معرِّف عميل Android لتطبيقك إذا لم يكن لديك معرّف من قبل. ستحتاج إلى تحديد اسم حزمة تطبيقك وتوقيع SHA-1.
    1. انتقِل إلى صفحة "بيانات الاعتماد".
    2. انقر على إنشاء بيانات اعتماد > معرِّف عميل OAuth.
    3. اختَر نوع تطبيق Android.
  4. في صفحة "بيانات الاعتماد"، أنشِئ معرِّف عميل جديدًا من نوع "تطبيق الويب" إذا لم يسبق لك إجراء ذلك. يمكنك تجاهل الحقلين "مصادر JavaScript المسموح بها" و"معرّفات الموارد المنتظمة (URI) المعتمَدة لإعادة التوجيه" في الوقت الحالي. سيتم استخدام معرِّف العميل هذا لتحديد خادم الخلفية عند اتصاله بخدمات المصادقة من Google.
    1. انتقِل إلى صفحة "بيانات الاعتماد".
    2. انقر على إنشاء بيانات اعتماد > معرِّف عميل OAuth.
    3. اختَر نوع تطبيق الويب.

تعريف التبعيات

في ملف Build.gradle الخاص بالوحدة، حدِّد التبعيات باستخدام أحدث إصدار من "مدير بيانات الاعتماد":

dependencies {
  // ... other dependencies

  implementation "androidx.credentials:credentials:<latest version>"
  implementation "androidx.credentials:credentials-play-services-auth:<latest version>"
  implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>"
}

إنشاء نسخة افتراضية لطلب تسجيل الدخول إلى حساب Google

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

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

أولاً، تحقّق مما إذا كان المستخدم يملك أي حسابات سبق استخدامها لتسجيل الدخول إلى تطبيقك من خلال استدعاء واجهة برمجة التطبيقات مع ضبط المعلَمة setFilterByAuthorizedAccounts على true. يمكن للمستخدمين الاختيار من بين الحسابات المتاحة لتسجيل الدخول.

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

تفعيل تسجيل الدخول التلقائي للمستخدمين المكرّري الزيارة (إجراء يُنصح به)

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

لتفعيل تسجيل الدخول التلقائي، استخدِم setAutoSelectEnabled(true). لا يمكن تسجيل الدخول تلقائيًا إلا عند استيفاء المعايير التالية:

  • توجد بيانات اعتماد واحدة تطابق الطلب، والتي يمكن أن تكون حساب Google أو كلمة مرور، وتتطابق بيانات الاعتماد هذه مع الحساب الافتراضي على الجهاز الذي يعمل بنظام تشغيل Android.
  • لم يُسجِّل المستخدم خروجه صراحةً.
  • لم يوقِف المستخدم تسجيل الدخول التلقائي في إعدادات حساب Google.
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

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

ضبط رقم هاتف لتحسين مستوى الأمان

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

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

إنشاء عملية "تسجيل الدخول باستخدام حساب Google"

في ما يلي خطوات إعداد عملية "تسجيل الدخول باستخدام حساب Google":

  1. أنشئ نسخة افتراضية من GetCredentialRequest، ثم أضِف عنصر googleIdOption الذي تم إنشاؤه سابقًا باستخدام addCredentialOption() لاسترداد بيانات الاعتماد.
  2. مرِّر هذا الطلب إلى مكالمة getCredential() (Kotlin) أو getCredentialAsync() (Java) لاسترداد بيانات الاعتماد المتاحة للمستخدم.
  3. بعد نجاح واجهة برمجة التطبيقات، يمكنك استخراج CustomCredential التي تؤدي إلى نتيجة بيانات GoogleIdTokenCredential.
  4. يجب أن يكون نوع CustomCredential مساويًا لقيمة GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL. حوِّل الكائن إلى GoogleIdTokenCredential باستخدام طريقة GoogleIdTokenCredential.createFrom.
  5. إذا نجحت عملية التحويل، يمكنك استخراج رقم تعريف GoogleIdTokenCredential والتحقّق منه، ثم مصادقة بيانات الاعتماد على الخادم.

  6. إذا تعذّر إتمام عملية التحويل باستخدام GoogleIdTokenParsingException، قد تحتاج إلى تعديل إصدار تسجيل الدخول باستخدام حساب Google.

  7. رصد أي أنواع بيانات اعتماد مُخصَّصة غير معروفة

val request: GetCredentialRequest = Builder()
  .addCredentialOption(googleIdOption)
  .build()

coroutineScope.launch {
  try {
    val result = credentialManager.getCredential(
      request = request,
      context = activityContext,
    )
    handleSignIn(result)
  } catch (e: GetCredentialException) {
    handleFailure(e)
  }
}

fun handleSignIn(result: GetCredentialResponse) {
  // Handle the successfully returned credential.
  val credential = result.credential

  when (credential) {

    // Passkey credential
    is PublicKeyCredential -> {
      // Share responseJson such as a GetCredentialResponse on your server to
      // validate and authenticate
      responseJson = credential.authenticationResponseJson
    }

    // Password credential
    is PasswordCredential -> {
      // Send ID and password to your server to validate and authenticate.
      val username = credential.id
      val password = credential.password
    }

    // GoogleIdToken credential
    is CustomCredential -> {
      if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
        try {
          // Use googleIdTokenCredential and extract id to validate and
          // authenticate on your server.
          val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)
        } catch (e: GoogleIdTokenParsingException) {
          Log.e(TAG, "Received an invalid google id token response", e)
        }
      } else {
        // Catch any unrecognized custom credential type here.
        Log.e(TAG, "Unexpected type of credential")
      }
    }

    else -> {
      // Catch any unrecognized credential type here.
      Log.e(TAG, "Unexpected type of credential")
    }
  }
}

بدء مسار زرّ "تسجيل الدخول باستخدام حساب Google"

لبدء تدفق زر "تسجيل الدخول باستخدام حساب Google"، استخدِم GetSignInWithGoogleOption بدلاً من GetGoogleIdOption:

val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder()
  .setServerClientId(WEB_CLIENT_ID)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

يمكنك التعامل مع GoogleIdTokenCredential التي تم إرجاعها كما هو موضَّح في مثال الرمز التالي.

fun handleSignIn(result: GetCredentialResponse) {
  // Handle the successfully returned credential.
  val credential = result.credential

  when (credential) {
    is CustomCredential -> {
      if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
        try {
          // Use googleIdTokenCredential and extract id to validate and
          // authenticate on your server.
          val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)
        } catch (e: GoogleIdTokenParsingException) {
          Log.e(TAG, "Received an invalid google id token response", e)
        }
      }
      else -> {
        // Catch any unrecognized credential type here.
        Log.e(TAG, "Unexpected type of credential")
      }
    }

    else -> {
      // Catch any unrecognized credential type here.
      Log.e(TAG, "Unexpected type of credential")
    }
  }
}

بعد إنشاء مثيل لطلب تسجيل الدخول إلى حساب Google، ابدأ مسار المصادقة بطريقة مماثلة كما هو مذكور في القسم تسجيل الدخول باستخدام حساب Google.

تفعيل الاشتراك للمستخدمين الجدد (يُنصح به)

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

إذا لم يتم العثور على أي بيانات اعتماد محفوظة (لم يعرض getGoogleIdOption أي حسابات Google)، اطلب من المستخدم الاشتراك. أولاً، تحقّق من وجود setFilterByAuthorizedAccounts(true) لمعرفة ما إذا كان هناك أي حسابات مستخدَمة سابقًا. وإذا لم يتم العثور على أي منها، اطلب من المستخدم الاشتراك من خلال حسابه على Google باستخدام setFilterByAuthorizedAccounts(false).

مثال:

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(false)
  .setServerClientId(SERVER_CLIENT_ID)
  .build()

بعد إنشاء مثيل لطلب الاشتراك في Google، ابدأ مسار المصادقة. إذا كان المستخدمون لا يريدون الاشتراك في Google، ننصحك باستخدام خدمات الملء التلقائي أو مفاتيح المرور لإنشاء الحسابات.

التعامل مع عملية تسجيل الخروج

عندما يسجّل المستخدم خروجه من تطبيقك، يمكنك استدعاء طريقة واجهة برمجة التطبيقات clearCredentialState() لمحو حالة بيانات اعتماد المستخدم الحالية من جميع مقدّمي بيانات الاعتماد. سيؤدي هذا إلى إعلام جميع مقدمي بيانات الاعتماد بأنه يجب محو أي جلسة بيانات اعتماد مخزنة للتطبيق المعني.

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