يؤدي تسجيل الدخول إلى حساب مرتبط إلى تفعيل ميزة تسجيل الدخول بنقرة واحدة باستخدام حساب Google لديهم حساب Google مرتبط بخدمتك. وهذا من شأنه تحسين تجربة المستخدم، حيث يمكنهم تسجيل الدخول بنقرة واحدة، ودون إعادة اسم المستخدم وكلمة المرور. كما أنه يقلل من فرص إنشاء المستخدمين حسابات مكرّرة على خدمتك.
تتوفَّر ميزة تسجيل الدخول باستخدام حساب مرتبط كجزء من عملية تسجيل الدخول بنقرة واحدة Android وهذا يعني أنك لن تحتاج إلى استيراد مكتبة منفصلة إذا كان تطبيقك ميزة "نقرة واحدة" مُفعَّلة حاليًا.
وستتعرف في هذا المستند على كيفية تعديل تطبيق Android تسجيل الدخول إلى حساب مرتبط
آلية العمل
- يمكنك الموافقة على عرض الحسابات المرتبطة أثناء تسجيل الدخول بنقرة واحدة.
- إذا سجّل المستخدم الدخول على Google وربط حسابه على Google حسابه على خدمتك، فسيتم عرض رمز مميز لرقم التعريف الحساب.
- يظهر للمستخدم رسالة تطلب منك تسجيل الدخول بنقرة واحدة مع خيار تسجيل الدخول إلى الخدمة باستخدام حسابهم المرتبط.
- إذا اختار المستخدم المتابعة باستخدام الحساب المرتبط، سيظهر الرمز المميز لمعرّف المستخدم. إلى تطبيقك. يمكنك مطابقة ذلك مع الرمز المميز الذي تم إرساله إلى في الخطوة 2 لتحديد المستخدم الذي سجّل الدخول.
ضبط إعدادات الجهاز
إعداد بيئة التطوير
احصل على أحدث "خدمات Google Play" من خلال مضيف التطوير:
ضمن أدوات حزمة تطوير البرامج (SDK)، ابحث عن خدمات Google Play.
إذا كانت حالة هذه الحزم غير مثبّتة، فحدد كلتيهما وانقر على تثبيت الحِزم:
إعداد تطبيقك
في ملف
build.gradle
على مستوى مشروعك، أضِف مستودع Maven من Google. في كل من القسمينbuildscript
وallprojects
.buildscript { repositories { google() } } allprojects { repositories { google() } }
إضافة الموارد التابعة لـ "الربط بـ Google" واجهة برمجة التطبيقات (API) في الوحدة ملف Gradle على مستوى التطبيق، ويكون عادةً
app/build.gradle
:dependencies { implementation 'com.google.android.gms:play-services-auth:21.2.0' }
تعديل تطبيق Android لإتاحة تسجيل الدخول باستخدام حساب مرتبط
في نهاية عملية تسجيل الدخول إلى الحساب المرتبط، يتم إرجاع رمز مميز للمعرّف إلى التطبيق. يجب التأكّد من صحة الرمز المميّز للمعرّف قبل تسجيل دخول المستخدم.
يوضح نموذج الرمز التالي بالتفصيل خطوات استرداد إثبات ملكية الرمز المميّز للمعرّف، وبعد ذلك سجّل دخول المستخدم.
إنشاء نشاط لتلقّي نتيجة القصد من تسجيل الدخول
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") } });
إنشاء طلب تسجيل الدخول
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()
فتح رسالة الغرض من تسجيل الدخول في انتظار المراجعة
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 على الرمز المميّز للمعرّف بشكل صحيح. استخدام مفاتيح Google العامة
(متوفّرة في
JWK أو
PEM)
للتحقق من توقيع الرمز المميّز. يتم تدوير هذه المفاتيح بانتظام؛ فحص
عنوان
Cache-Control
في الردّ لتحديد وقت فيجب عليك استردادها مرة أخرى. - تساوي قيمة
aud
في الرمز المميّز للمعرّف إحدى قيم التطبيق. معرِّفات العملاء. وتُعدّ هذه العملية ضرورية لمنع رموز التعريف المميزة التي يتم إصدارها إلى تطبيق يتم استخدامه للوصول إلى بيانات حول المستخدم نفسه على خادم الخلفية في تطبيقك. - تساوي قيمة
iss
في الرمز المميّز للمعرّفaccounts.google.com
أوhttps://accounts.google.com
. - لم ينتهِ وقت انتهاء الصلاحية (
exp
) للرمز المميّز للمعرّف. - إذا كنت بحاجة إلى التحقّق من أنّ الرمز المميّز للمعرّف يمثّل Google Workspace أو Cloud
حساب مؤسسة، يمكنك الاطّلاع على المطالبة
hd
التي تشير إلى أنّه تمت استضافته مجال المستخدم. ويجب استخدام ذلك عند قصر الوصول إلى مورد على أعضاء ومجالات معينة. يشير عدم وجود هذه المطالبة إلى أن الحساب لا ينتمي إلى نطاق تستضيفه Google.
باستخدام الحقول email
وemail_verified
وhd
، يمكنك تحديد ما إذا كان
تستضيف Google عنوان بريد إلكتروني وموثوقًا به. في الحالات التي تكون فيها Google موثوقة،
يكون المستخدم معروفًا كمالك الحساب الشرعي، ويمكنك تخطي كلمة المرور أو
طرق التحدي.
الحالات التي تكون فيها Google موثوقة:
- السمة
email
هي اللاحقة@gmail.com
، وهذا حساب Gmail. email_verified
صحيح وتم ضبطhd
، هذا حساب G Suite.
يمكن للمستخدمين التسجيل للحصول على حسابات Google بدون استخدام Gmail أو G Suite. فعندما
لا يحتوي email
على اللاحقة @gmail.com
وhd
غير موجود، كما أن Google لا
موثوقة وكلمة المرور أو طرق التحقق الأخرى للتحقق
المستخدم. يمكن أن يكون email_verified
صحيحًا أيضًا لأن Google تحققت في البداية من صحة
المستخدم عند إنشاء حساب Google، ولكن ملكية الجهة الخارجية
ربما تغير حساب بريدك الإلكتروني منذ ذلك الحين.
وبدلاً من كتابة رمزك الخاص لتنفيذ خطوات التحقّق هذه،
أنصحك باستخدام مكتبة برامج Google API لنظامك الأساسي أو غرض عام
مكتبة JWT. للتطوير وتصحيح الأخطاء، يمكنك الاتصال بـ tokeninfo
بنقطة نهاية التحقق من الصحة.
استخدام مكتبة برامج 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
ومطالبة iss
ومطالبة مقدَّمة عبرexp
إذا كنت بحاجة إلى التحقّق من أنّ الرمز المميّز للمعرّف يمثّل Google Workspace أو Cloud
حساب مؤسسة، يمكنك إثبات ملكية المطالبة hd
من خلال التحقّق من اسم النطاق.
التي يتم إرجاعها باستخدام الطريقة Payload.getHostedDomain()
.
استدعاء نقطة نهايةTokeninfo
هناك طريقة سهلة للتحقّق من صحة توقيع الرمز المميّز لرقم التعريف من أجل تصحيح الأخطاء وهي من خلال:
استخدام نقطة النهاية tokeninfo
. يتضمن استدعاء نقطة النهاية هذه
إضافي من بيانات الشبكة يُجري معظم عمليات التحقق نيابةً عنك أثناء إجراء اختبار
والتحقق من صحته واستخراج حمولة البيانات في التعليمات البرمجية الخاصة بك. التطبيق غير مناسب للاستخدام في مرحلة الإنتاج
حيث قد يتم تقييد الطلبات أو قد تكون عرضة لأخطاء متقطعة.
للتحقّق من صحة رمز مميّز لرقم التعريف باستخدام نقطة النهاية tokeninfo
، يجب إنشاء HTTPS.
POST أو GET إلى نقطة النهاية، ومرر الرمز المميز للمعرف في
مَعلمة id_token
.
على سبيل المثال، للتحقق من صحة الرمز المميز "XYZ123"، قدِّم طلب GET التالي:
https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123
إذا تمّ توقيع الرمز المميّز بشكل صحيح وكان iss
وexp
المطالبات التي تضم القيم المتوقعة، ستحصل على استجابة HTTP 200، حيث يشير نص
يحتوي على مطالبات الرموز المميّزة للمعرّف بتنسيق JSON.
إليك مثال على الرد:
{ // These six fields are included in all Google ID Tokens. "iss": "https://accounts.google.com", "sub": "110169484474386276334", "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "iat": "1433978353", "exp": "1433981953", // These seven fields are only included when the user has granted the "profile" and // "email" OAuth scopes to the application. "email": "testuser@gmail.com", "email_verified": "true", "name" : "Test User", "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg", "given_name": "Test", "family_name": "User", "locale": "en" }
إذا كنت بحاجة إلى التحقّق من أنّ الرمز المميّز للمعرّف يمثّل حسابًا على Google Workspace، يمكنك التحقّق من
المطالبة hd
، التي تشير إلى النطاق المستضاف للمستخدم. يجب استخدام هذا في الحالات
تقييد الوصول إلى مورد لأعضاء نطاقات معينة فقط. عدم وجود هذه المطالبة
إلى أنّ الحساب لا ينتمي إلى نطاق مستضاف على Google Workspace.