يؤدي تسجيل الدخول إلى حساب مرتبط إلى تفعيل ميزة تسجيل الدخول بنقرة واحدة باستخدام حساب 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 هي الطريقة الموصى بها لإثبات صحة الرموز المميّزة لمعرّف 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()
.
جارٍ استدعاء نقطة نهاية iconinfo
تتوفّر طريقة سهلة للتحقّق من صحة توقيع الرمز المميّز للمعرّف من أجل تصحيح الأخطاء، وهي استخدام نقطة النهاية 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.