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

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

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

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

آلية العمل

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

ضبط إعدادات الجهاز

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

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

  1. افتح مدير حزمة تطوير البرامج (SDK) لنظام التشغيل Android.
  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. تشغيل النية "تسجيل الدخول في انتظار المراجعة"

    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

إنّ استخدام مكتبة Java Google API Client Library هو الطريقة المقترَحة للتحقّق من صحة رموز تعريف 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 claim وiss claim وexp claim.

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