במדריך הזה מוסבר איך מטמיעים את התכונה 'כניסה באמצעות חשבון Google'. המדריך כולל את השלבים הבאים:
- מוסיפים יחסי תלות לאפליקציה.
- יצירת מופע של
CredentialManager. - יוצרים את התהליך של הגיליון התחתון.
- יוצרים את תהליך העבודה של הכפתור.
- טיפול בתגובת הכניסה.
- לטפל בשגיאות.
- טיפול ביציאה מהחשבון.
הוספת יחסי תלות לאפליקציה
בקובץ build.gradle של המודול, מצהירים על יחסי תלות באמצעות הגרסה העדכנית של Credential Manager, Play Services Auth ו-googleid:
Kotlin
dependencies { implementation("androidx.credentials:credentials:1.6.0-rc02") implementation("androidx.credentials:credentials-play-services-auth:1.6.0-rc02") implementation("com.google.android.libraries.identity.googleid:googleid:<latest version>") }
Groovy
dependencies { implementation "androidx.credentials:credentials:1.6.0-rc02" implementation "androidx.credentials:credentials-play-services-auth:1.6.0-rc02" implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>" }
יצירת מופע של Credential Manager
משתמשים בהקשר של האפליקציה או הפעילות כדי ליצור אובייקט CredentialManager.
// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)
יצירת התהליך של הגיליון התחתון
הגיליון התחתון הוא ממשק המשתמש המובנה של מנהל פרטי הכניסה. ממשק המשתמש הזה מאפשר חוויה עקבית בכל שיטות האימות, כמו סיסמאות, מפתחות גישה וכניסה באמצעות חשבון Google.
הגדרת בקשת הכניסה לחשבונות שכבר אושרו
מנסים לשלוח בקשה לכניסה באמצעות חשבון Google עם GetGoogleIdOption כדי לאחזר את טוקן הזהות של המשתמש ב-Google.
בדוגמאות הקוד הבאות נבדק אם החשבון הוא חשבון מורשה.
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(true)
.setServerClientId(WEB_CLIENT_ID)
.setAutoSelectEnabled(true)
.setNonce(generateSecureRandomNonce())
.build()
אובייקט הבקשה googleIdOption מוגדר באופן הבא:
סינון חשבונות שאושרו בעבר: כדי לאחזר את החשבונות שאושרו וששימשו בעבר לכניסה לאפליקציה, צריך להגדיר את
setFilterByAuthorizedAccountsל-true.שימו לב שערך ברירת המחדל של
setFilterByAuthorizedAccountsהואtrue, כלומר התנהגות ברירת המחדל של ממשק המשתמש של הגיליון התחתון היא להציג רק חשבונות שאושרו בעבר.מגדירים את מזהה הלקוח של השרת: מגדירים את הפרמטר
setServerClientId. webClientIdהוא מזהה לקוח האינטרנט שהגדרתם עבור OAuth בפרויקט Google Cloud שלכם במהלך השלמת הדרישות המוקדמות.הפעלת כניסה אוטומטית (אופציונלי): כדי להפעיל כניסה אוטומטית למשתמשים חוזרים, משתמשים ב-
setAutoSelectEnabled(true)וב-setFilterByAuthorizedAccounts(true). למשתמשי האפליקציה, הפעולה הזו תמנע חיכוך מיותר אם הם כבר נכנסו לחשבון בעבר.כניסה אוטומטית אפשרית רק אם מתקיימים הקריטריונים הבאים:
- במכשיר יש רק חשבון מורשה אחד, ובעבר השתמשו בחשבון המורשה הזה כדי להיכנס לאפליקציה במכשיר. אם יש במכשיר כמה חשבונות מורשים, הכניסה האוטומטית מושבתת.
- המשתמש לא יצא במפורש מהאפליקציה במהלך ההפעלה הקודמת.
- המשתמש לא השבית את הכניסה האוטומטית בהגדרות חשבון Google.
הגדרת צופן חד-פעמי (nonce) (אופציונלי): כדי להפעיל אבטחה משופרת, מגדירים צופן חד-פעמי (nonce) לאימות בצד השרת. כדי למנוע מתקפות שידור חוזר, אפשר לכלול ערך חד-פעמי (nonce) לאימות בצד השרת באמצעות
setNonce(). מוודאים שהקוד בצד השרת מאמת את זהות הנונסים של הבקשה והתגובה.כדי ליצור את הערך החד-פעמי, משתמשים בפונקציה שדומה לפונקציה הבאה, שיוצרת ערך חד-פעמי אקראי חזק מבחינה קריפטוגרפית באורך שצוין ומקודדת אותו באמצעות
Base64:
fun generateSecureRandomNonce(byteLength: Int = 32): String {
val randomBytes = ByteArray(byteLength)
SecureRandom().nextBytes(randomBytes)
return Base64.encodeToString(randomBytes, Base64.NO_WRAP or Base64.URL_SAFE or Base64.NO_PADDING)
}
בקשת כניסה
בודקים אם למשתמש יש חשבון מורשה במכשיר באמצעות הפעלת method מסוג getCredential:
val request: GetCredentialRequest = GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()
coroutineScope {
try {
val result = credentialManager.getCredential(
request = request,
context = activityContext,
)
handleSignIn(result)
} catch (e: GetCredentialException) {
// Handle failures
}
}
הגדרת בקשת הכניסה אם אין חשבונות מורשים זמינים
אם אין משתמשים מורשים לאפליקציה במכשיר, הפונקציה CredentialManager
מחזירה את הערך NoCredentialException. בתרחיש הזה, צריך להשבית את המסנן של החשבונות המורשים כדי שהמשתמש יוכל להירשם באמצעות חשבון אחר.
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(false)
.setServerClientId(WEB_CLIENT_ID)
.setNonce(generateSecureRandomNonce())
.build()
לאחר מכן, מבקשים להיכנס בדומה לאופן שבו נכנסתם לחשבונות המורשים.
יצירת תהליך כפתור
אפשר להשתמש בלחצן אם רוצים שהמשתמשים יוכלו להיכנס באמצעות חשבון Google בתנאים הבאים:
- המשתמש סגר את ממשק המשתמש של הגיליון התחתון של Credential Manager.
- אין חשבונות Google במכשיר.
- צריך לבצע אימות מחדש של החשבונות הקיימים במכשיר.
יצירת ממשק משתמש של כפתור
אפשר לעשות את זה באמצעות לחצן Jetpack פיתוח נייטיב, אבל אפשר גם להשתמש בסמל מותג שאושר מראש מתוך הדף הנחיות המיתוג של 'כניסה באמצעות חשבון Google'.
יצירת תהליך הכניסה
יוצרים בקשה לכניסה באמצעות חשבון Google עם GetSignInWithGoogleOption כדי לאחזר אסימון מזהה של Google.
val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder(
serverClientId = WEB_CLIENT_ID
).setNonce(generateSecureRandomNonce())
.build()
לאחר מכן, מבקשים להיכנס באופן דומה למה שעשיתם בממשק של הגיליון התחתון.
יצירת פונקציית הכניסה המשותפת לגיליון התחתון ולכפתור
כדי לטפל בכניסה, מבצעים את השלבים הבאים:
- משתמשים בפונקציה
getCredential()של CredentialManager. אם התגובה מוצלחת, מחלצים אתCustomCredential, שצריך להיות מסוגGoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL. ממירים את האובייקט ל-
GoogleIdTokenCredentialבאמצעות השיטהGoogleIdTokenCredential.createFrom().מאמתים את פרטי הכניסה בשרת הצד המסתמך.
חשוב לוודא שאתם מטפלים בשגיאות בצורה נכונה.
fun handleSign(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 the ID for server-side validation.
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 במכשיר והוא יחליט להיכנס לחשבון אחר. לדוגמה, אפשר לספק את המידע הזה בדף ההגדרות.
ספק פרטי כניסה עשוי לאחסן סשן פעיל של פרטי כניסה ולהשתמש בו כדי להגביל את אפשרויות הכניסה לבקשות כניסה עתידיות. לדוגמה, היא יכולה לתת עדיפות לפרטי הכניסה הפעילים על פני כל פרטי כניסה אחרים שזמינים.
כשמשתמש מתנתק מהאפליקציה, צריך להפעיל את שיטת ה-API clearCredentialState() כדי לנקות את מצב פרטי הכניסה הנוכחיים של המשתמש מכל ספקי פרטי הכניסה.
הפעולה הזו תשלח הודעה לכל ספקי האישורים שצריך למחוק את סשן האישורים ששמור עבור האפליקציה שצוינה, כדי שבפעם הבאה למשתמשים יהיו אפשרויות כניסה מלאות.