تسجيل الدخول إلى الحساب المرتبط على أجهزة Android

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

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

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

آلية العمل

  1. يمكنك الموافقة على عرض الحسابات المرتبطة أثناء عملية تسجيل الدخول باستخدام ميزة "نقرة واحدة".
  2. إذا سجّل المستخدم الدخول على Google وربط حساب Google بحسابه على خدمتك، سيتم عرض رمز مميّز للمعرّف للحساب المرتبط.
  3. يظهر للمستخدم طلب تسجيل الدخول باستخدام ميزة "نقرة واحدة" مع خيار تسجيل الدخول إلى خدمتك باستخدام حسابه المرتبط.
  4. إذا اختار المستخدم المتابعة باستخدام الحساب المرتبط، سيتم إرجاع الرمز المميّز لرقم تعريف المستخدم إلى تطبيقك. يمكنك مطابقة هذا الرمز مع الرمز الذي تم إرساله إلى خادمك في الخطوة 2 لتحديد المستخدم الذي سجّل الدخول.

الإعداد

لإعداد ميزة "تسجيل الدخول إلى الحساب المرتبط"، عليك ضبط بيئة التطوير وتطبيقك.

إعداد بيئة التطوير

احصل على أحدث إصدار من "خدمات Google Play" على مضيف التطوير:

  1. افتح Android SDK Manager.
  1. ضِمن أدوات حزمة تطوير البرامج (SDK)، ابحث عن خدمات Google Play.

  2. إذا لم تكن حالة هذه الحزم "مثبّتة"، اختَر كليهما وانقر على تثبيت الحزم.

إعداد تطبيقك

  1. في ملف build.gradle على مستوى المشروع، أدرِج مستودع Maven من Google في كلّ من القسمَين buildscript وallprojects.

    buildscript {
        repositories {
            google()
        }
    }
    
    allprojects {
        repositories {
            google()
        }
    }
    
  2. أضِف تبعيات واجهة برمجة التطبيقات "الربط بحساب Google" إلى ملف gradle على مستوى التطبيق في الوحدة، والذي يكون عادةً app/build.gradle:

    dependencies {
      implementation 'com.google.android.gms:play-services-auth:21.3.0'
    }
    

تعديل تطبيق Android لإتاحة ميزة "تسجيل الدخول إلى الحساب المرتبط"

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

يوضّح نموذج الرمز البرمجي التالي خطوات استرداد الرمز المميّز للمعرّف والتحقّق منه، ثم تسجيل دخول المستخدم.

  1. إنشاء نشاط لتلقّي نتيجة طلب تسجيل الدخول

    Kotlin

      private val activityResultLauncher = registerForActivityResult(
        ActivityResultContracts.StartIntentSenderForResult()) { result ->
        if (result.resultCode == RESULT_OK) {
          try {
            val signInCredentials = Identity.signInClient(this)
                                    .signInCredentialFromIntent(result.data)
            // Review the Verify the integrity of the ID token section for
            // details on how to verify the ID token
            verifyIdToken(signInCredential.googleIdToken)
          } catch (e: ApiException) {
            Log.e(TAG, "Sign-in failed with error code:", e)
          }
        } else {
          Log.e(TAG, "Sign-in failed")
        }
      }
    

    Java

      private final ActivityResultLauncher<IntentSenderResult>
        activityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartIntentSenderForResult(),
        result -> {
        If (result.getResultCode() == RESULT_OK) {
            try {
              SignInCredential signInCredential = Identity.getSignInClient(this)
                             .getSignInCredentialFromIntent(result.getData());
              verifyIdToken(signInCredential.getGoogleIdToken());
            } catch (e: ApiException ) {
              Log.e(TAG, "Sign-in failed with error:", e)
            }
        } else {
            Log.e(TAG, "Sign-in failed")
        }
    });
    
  2. إنشاء طلب تسجيل الدخول

    Kotlin

    private val tokenRequestOptions =
    GoogleIdTokenRequestOptions.Builder()
      .supported(true)
      // Your server's client ID, not your Android client ID.
      .serverClientId(getString("your-server-client-id")
      .filterByAuthorizedAccounts(true)
      .associateLinkedAccounts("service-id-of-and-defined-by-developer",
                               scopes)
      .build()
    

    Java

     private final GoogleIdTokenRequestOptions tokenRequestOptions =
         GoogleIdTokenRequestOptions.Builder()
      .setSupported(true)
      .setServerClientId("your-service-client-id")
      .setFilterByAuthorizedAccounts(true)
      .associateLinkedAccounts("service-id-of-and-defined-by-developer",
                                scopes)
      .build()
    
  3. تشغيل intent "تسجيل الدخول في انتظار المراجعة"

    Kotlin

     Identity.signInClient(this)
        .beginSignIn(
      BeginSignInRequest.Builder()
        .googleIdTokenRequestOptions(tokenRequestOptions)
      .build())
        .addOnSuccessListener{result ->
          activityResultLauncher.launch(result.pendingIntent.intentSender)
      }
      .addOnFailureListener {e ->
        Log.e(TAG, "Sign-in failed because:", e)
      }
    

    Java

     Identity.getSignInClient(this)
      .beginSignIn(
        BeginSignInRequest.Builder()
          .setGoogleIdTokenRequestOptions(tokenRequestOptions)
          .build())
      .addOnSuccessListener(result -> {
        activityResultLauncher.launch(
            result.getPendingIntent().getIntentSender());
    })
    .addOnFailureListener(e -> {
      Log.e(TAG, "Sign-in failed because:", e);
    });
    

التحقّق من سلامة رمز التعريف المميّز

استخدام مكتبة عملاء Google API

يُعدّ استخدام مكتبة عميل Google API للغة Java الطريقة المقترَحة للتحقّق من صحة الرموز المميّزة لحساب Google في بيئة التشغيل الفعلي.

Java

  import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
  import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
  import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;

  ...

  GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
      // Specify the CLIENT_ID of the app that accesses the backend:
      .setAudience(Collections.singletonList(CLIENT_ID))
      // Or, if multiple clients access the backend:
      //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
      .build();

  // (Receive idTokenString by HTTPS POST)

  GoogleIdToken idToken = verifier.verify(idTokenString);
  if (idToken != null) {
    Payload payload = idToken.getPayload();

    // Print user identifier
    String userId = payload.getSubject();
    System.out.println("User ID: " + userId);

    // Get profile information from payload
    String email = payload.getEmail();
    boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
    String name = (String) payload.get("name");
    String pictureUrl = (String) payload.get("picture");
    String locale = (String) payload.get("locale");
    String familyName = (String) payload.get("family_name");
    String givenName = (String) payload.get("given_name");

    // Use or store profile information
    // ...

  } else {
    System.out.println("Invalid ID token.");
  }

تتحقّق طريقة GoogleIdTokenVerifier.verify() من توقيع JWT والمطالبة aud والمطالبة iss والمطالبة exp.

إذا كنت بحاجة إلى التحقّق من أنّ الرمز المميّز للتعريف يمثّل حسابًا لمؤسسة على Google Workspace أو Cloud، يمكنك التحقّق من مطالبة hd من خلال مراجعة اسم النطاق الذي تعرضه طريقة Payload.getHostedDomain().