יש להשתמש בלקוח הכניסה בהקשה אחת כדי לבקש מהמשתמש הרשאה לאחזר את הנתונים אחד מפרטי הכניסה שהם השתמשו בו בעבר כדי להיכנס לאפליקציה שלכם. האלה פרטי הכניסה יכולים להיות שילוב של חשבון Google או של שם משתמש וסיסמה הם שמרו ב-Google באמצעות Chrome, המילוי האוטומטי של Android או Smart Lock סיסמאות.
אחרי שפרטי הכניסה מאוחזרים בהצלחה, אפשר להשתמש בהם בצורה חלקה כניסה של המשתמש לחשבון באפליקציה.
אם המשתמש לא שמר פרטי כניסה, לא יוצג ממשק משתמש ותוכלו לספק את החוויה הרגילה שלך ללא חיבור לחשבון.
איפה כדאי להשתמש בכניסה באמצעות One Tap?
אם האפליקציה מחייבת משתמשים להיכנס לחשבון, יש להציג את ממשק המשתמש בהקשה אחת בכניסה לחשבון מסך. האפשרות הזו יכולה להיות שימושית גם אם כבר יש לך אפשרות של 'כניסה באמצעות חשבון Google' לחצן: כי ניתן להגדיר את ממשק המשתמש של One Tap כך שיציג רק פרטי כניסה שימש בעבר לכניסה, הוא יכול לשמש כתזכורת למשתמשים שלעיתים רחוקות להיכנס באופן שבו הם נכנסו בפעם האחרונה, ולמנוע מהם יצירת חשבונות חדשים באפליקציה.
אם הכניסה לאפליקציה היא אופציונלית, כדאי להשתמש בכניסה בהקשה אחת בכל מכשיר ליהנות מחוויית משתמש משופרת באמצעות כניסה לחשבון. לדוגמה, אם משתמשים יכולים לדפדף בתוכן באמצעות האפליקציה כשלא מחוברים לחשבון, אבל אפשר רק לפרסם תגובות או להוסיף פריטים לעגלת קניות אחרי הכניסה לחשבון, זה יהיה הקשר הגיוני כניסה בהקשה אחת.
אפליקציות אופציונליות לכניסה צריכות גם להשתמש בכניסה באמצעות הקשה אחת במסכי הכניסה שלהן. מהסיבות שצוינו למעלה.
לפני שמתחילים
- מגדירים את הפרויקט במסוף Google APIs ואת פרויקט Android כפי שמתואר ב תחילת העבודה עם כניסה באמצעות הקשה אחת.
- אם אתם תומכים בכניסה מבוססת סיסמה, כדאי לבצע אופטימיזציה של האפליקציה עבור מילוי אוטומטי (או שימוש ב-Smart Lock לסיסמאות) כדי שמשתמשים יוכלו לשמור את פרטי הכניסה של הסיסמה אחרי הכניסה.
1. הגדרת הלקוח לכניסה באמצעות הקשה אחת
אפשר להגדיר את לקוח הכניסה בהקשה אחת כדי להכניס משתמשים עם פריטים שמורים סיסמאות, חשבונות Google שמורים או אחד מהשניים. (מומלץ לתמוך בשניהם, הפעלה של יצירת חשבון בהקשה אחת למשתמשים חדשים וכניסה אוטומטית או בהקשה אחת לכמה שיותר משתמשים חוזרים).
אם נכנסים לאפליקציה שלך באמצעות סיסמה, צריך להשתמש ב-setPasswordRequestOptions()
כדי
להפעיל בקשות לפרטי כניסה לסיסמאות.
אם באפליקציה שלך נעשה שימוש ב'כניסה באמצעות חשבון Google', יש להשתמש ב-setGoogleIdTokenRequestOptions()
כדי
הפעלה והגדרה של בקשות לאסימוני מזהה של Google:
מגדירים את מזהה הלקוח של השרת למזהה שיצרתם ב-Google APIs של Google. לתשומת ליבכם: זהו מזהה הלקוח של השרת שלכם, ולא מזהה הלקוח ב-Android.
מגדירים את הלקוח לסינון לפי חשבונות מורשים. כשמפעילים את האפשרות הזו האפשרות הרצויה, הלקוח ב-One Tap רק מבקש מהמשתמשים להיכנס לאפליקציה באמצעות חשבונות Google שהם כבר השתמשו בהם בעבר. פעולה זו יכולה לעזור למשתמשים לחתום בהצלחה כאשר הם לא בטוחים אם כבר יש להם חשבון, או חשבון Google שבו הם השתמשו, ומונעים מהמשתמשים ליצור בטעות חשבון חדש חשבונות באפליקציה.
אם אתם רוצים לאפשר למשתמשים להיכנס לחשבון באופן אוטומטי כשהדבר אפשרי, אתם צריכים להפעיל את התכונה עם
setAutoSelectEnabled()
. כניסה אוטומטית אפשרית כאשר הקריטריונים הבאים:- למשתמש יש רק פרטי כניסה אחד שנשמרו לאפליקציה. כלומר, מודל אחד נשמר סיסמה או חשבון Google שמור אחד.
- המשתמש לא השבית את הכניסה האוטומטית הגדרות חשבון Google.
אמנם לא חובה, אבל מומלץ מאוד להשתמש ב-nonce לשפר את אבטחת הכניסה ולהימנע מהתקפות חוזרות. כדאי להשתמש setNonce כדי לכלול צופן חד-פעמי בכל בקשה. לעיון ב- SafetyNet קבלת צופן חד-פעמי לקבלת הצעות ופרטים נוספים על יצירת צופן חד-פעמי.
Java
public class YourActivity extends AppCompatActivity { // ... private SignInClient oneTapClient; private BeginSignInRequest signInRequest; @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); oneTapClient = Identity.getSignInClient(this); signInRequest = BeginSignInRequest.builder() .setPasswordRequestOptions(PasswordRequestOptions.builder() .setSupported(true) .build()) .setGoogleIdTokenRequestOptions(GoogleIdTokenRequestOptions.builder() .setSupported(true) // Your server's client ID, not your Android client ID. .setServerClientId(getString(R.string.default_web_client_id)) // Only show accounts previously used to sign in. .setFilterByAuthorizedAccounts(true) .build()) // Automatically sign in when exactly one credential is retrieved. .setAutoSelectEnabled(true) .build(); // ... } // ... }
Kotlin
class YourActivity : AppCompatActivity() { // ... private lateinit var oneTapClient: SignInClient private lateinit var signInRequest: BeginSignInRequest override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) oneTapClient = Identity.getSignInClient(this) signInRequest = BeginSignInRequest.builder() .setPasswordRequestOptions(BeginSignInRequest.PasswordRequestOptions.builder() .setSupported(true) .build()) .setGoogleIdTokenRequestOptions( BeginSignInRequest.GoogleIdTokenRequestOptions.builder() .setSupported(true) // Your server's client ID, not your Android client ID. .setServerClientId(getString(R.string.your_web_client_id)) // Only show accounts previously used to sign in. .setFilterByAuthorizedAccounts(true) .build()) // Automatically sign in when exactly one credential is retrieved. .setAutoSelectEnabled(true) .build() // ... } // ... }
2. חיפוש משתמש מחובר
אם הפעילות שלך יכולה לשמש משתמש מחובר או משתמש שלא מחובר לחשבון, הסטטוס של המשתמש לפני הצגת ממשק המשתמש לכניסה בהקשה אחת.
כדאי גם לבדוק אם המשתמש כבר סירב להשתמש בשירות כדי להיכנס לחשבון בהקשה אחת, אפשר לסגור את ההצעה לפעולה או להקיש מחוץ לה. מי יכול יהיה פשוט נכס בוליאני של הפעילות שלכם. (ראו איך מפסיקים להציג את ממשק המשתמש בהקשה אחת בהמשך).
3. הצגת ממשק המשתמש לכניסה בהקשה אחת
אם המשתמש לא מחובר לחשבון ולא סירב כבר להיכנס לחשבון בהקשה אחת,
קוראים ל-method beginSignIn()
של אובייקט הלקוח, ומצרפים מאזינים לאובייקט
Task
מוחזרת. בדרך כלל אפליקציות עושות זאת בשיטת onCreate()
של הפעילות
או אחרי מעברים בין מסכים כשמשתמשים בארכיטקטורה של פעילות יחידה.
הלקוח One Tap יקרא ל'מאזינים המוצלחים' אם למשתמש יש פריטים שמורים
פרטי הכניסה לאפליקציה. בקרב המאזינים להצלחה, קבלו את הכוונה הממתינה
את התוצאה Task
ומעבירים אותה ל-startIntentSenderForResult()
כדי להתחיל
ממשק משתמש לכניסה באמצעות הקשה אחת.
אם למשתמש אין פרטי כניסה שמורים, הלקוח One Tap יקרא ש-נכשל. במקרה הזה לא צריך לעשות שום דבר: אפשר פשוט להמשיך הצגת חוויית המשתמש כשאתם לא מחוברים לחשבון באפליקציה. עם זאת, אם יש תמיכה בתכונה 'הקשה אחת' הרשמה, אתם יכולים להתחיל את התהליך הזה כאן כדי ליצור חשבון בצורה חלקה חוויה אישית. תוכלו להיעזר במאמר יצירת חשבונות חדשים בהקשה אחת.
Java
oneTapClient.beginSignIn(signUpRequest)
.addOnSuccessListener(this, new OnSuccessListener<BeginSignInResult>() {
@Override
public void onSuccess(BeginSignInResult result) {
try {
startIntentSenderForResult(
result.getPendingIntent().getIntentSender(), REQ_ONE_TAP,
null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Couldn't start One Tap UI: " + e.getLocalizedMessage());
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// No saved credentials found. Launch the One Tap sign-up flow, or
// do nothing and continue presenting the signed-out UI.
Log.d(TAG, e.getLocalizedMessage());
}
});
Kotlin
oneTapClient.beginSignIn(signInRequest)
.addOnSuccessListener(this) { result ->
try {
startIntentSenderForResult(
result.pendingIntent.intentSender, REQ_ONE_TAP,
null, 0, 0, 0, null)
} catch (e: IntentSender.SendIntentException) {
Log.e(TAG, "Couldn't start One Tap UI: ${e.localizedMessage}")
}
}
.addOnFailureListener(this) { e ->
// No saved credentials found. Launch the One Tap sign-up flow, or
// do nothing and continue presenting the signed-out UI.
Log.d(TAG, e.localizedMessage)
}
4. טיפול בתשובה של המשתמש
תגובת המשתמש להודעת הכניסה בהקשה אחת תדווח לאפליקציה שלך
באמצעות השיטה onActivityResult()
של הפעילות שלך. אם המשתמש בחר להיכנס,
התוצאה תהיה פרטי כניסה שמורים. אם המשתמש סירב להיכנס,
על ידי סגירת ממשק המשתמש בהקשה אחת או הקשה מחוץ לו, התוצאה תחזור עם
קוד RESULT_CANCELED
. האפליקציה שלך צריכה לטפל בשתי האפשרויות.
כניסה באמצעות פרטי כניסה שאוחזרו
אם המשתמש בחר לשתף את פרטי הכניסה עם האפליקציה, אפשר לאחזר אותם על ידי
העברה של נתוני Intent מ-onActivityResult()
אל הלקוח ב-One Tap
getSignInCredentialFromIntent()
. פרטי הכניסה יהיו בעלי ערך שאינו null
נכס googleIdToken
אם המשתמש שיתף עם פרטי כניסה לחשבון Google
את האפליקציה, או נכס password
שאינו null אם המשתמש שיתף סיסמה שמורה.
השתמשו בפרטי הכניסה כדי לבצע אימות באמצעות הקצה העורפי של האפליקציה.
- אם אוחזרו צמד של שם משתמש וסיסמה, משתמשים בהם כדי להיכנס לאותו חשבון כפי שהייתם עושים אם המשתמש היה מספק אותם באופן ידני.
אם אוחזרו פרטי כניסה לחשבון Google, השתמשו באסימון המזהה כדי לבצע אימות ישר מהקצה העורפי. אם בחרתם להשתמש בצפנים חד-פעמיים כדי למנוע הפעלה חוזרת מתקפות בודקות את ערך התגובה בשרת הקצה העורפי שלכם. צפייה אימות באמצעות קצה עורפי באמצעות אסימונים מזהים
Java
public class YourActivity extends AppCompatActivity { // ... private static final int REQ_ONE_TAP = 2; // Can be any integer unique to the Activity. private boolean showOneTapUI = true; // ... @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQ_ONE_TAP: try { SignInCredential credential = oneTapClient.getSignInCredentialFromIntent(data); String idToken = credential.getGoogleIdToken(); String username = credential.getId(); String password = credential.getPassword(); if (idToken != null) { // Got an ID token from Google. Use it to authenticate // with your backend. Log.d(TAG, "Got ID token."); } else if (password != null) { // Got a saved username and password. Use them to authenticate // with your backend. Log.d(TAG, "Got password."); } } catch (ApiException e) { // ... } break; } } }
Kotlin
class YourActivity : AppCompatActivity() { // ... private val REQ_ONE_TAP = 2 // Can be any integer unique to the Activity private var showOneTapUI = true // ... override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQ_ONE_TAP -> { try { val credential = oneTapClient.getSignInCredentialFromIntent(data) val idToken = credential.googleIdToken val username = credential.id val password = credential.password when { idToken != null -> { // Got an ID token from Google. Use it to authenticate // with your backend. Log.d(TAG, "Got ID token.") } password != null -> { // Got a saved username and password. Use them to authenticate // with your backend. Log.d(TAG, "Got password.") } else -> { // Shouldn't happen. Log.d(TAG, "No ID token or password!") } } } catch (e: ApiException) { // ... } } } } // ... }
הפסקת ההצגה של ממשק המשתמש בהקשה אחת
אם המשתמש סירב להיכנס לחשבון, הוא יתקשר למספר getSignInCredentialFromIntent()
תקפיץ ApiException
עם קוד הסטטוס CommonStatusCodes.CANCELED
.
במקרה כזה, עליכם להשבית באופן זמני את ממשק המשתמש לכניסה בהקשה אחת, כדי
שלא מעצבנים את המשתמשים באמצעות הנחיות חוזרות. הדוגמה הבאה משיגה
על ידי הגדרת נכס בפעילות, שבו היא משתמשת כדי לקבוע אם
כדי להציע למשתמש כניסה בהקשה אחת; אבל אפשר גם לשמור את הערך
SharedPreferences
או להשתמש בשיטה אחרת.
חשוב ליישם הגבלת קצב של בקשות כניסה באמצעות 'הקשה אחת'. אם לא עשיתם זאת, והמשתמש ביטל כמה הנחיות ברצף, הלקוח One Tap לא תשלח הודעה למשתמש במשך 24 השעות הבאות.
Java
public class YourActivity extends AppCompatActivity { // ... private static final int REQ_ONE_TAP = 2; // Can be any integer unique to the Activity. private boolean showOneTapUI = true; // ... @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQ_ONE_TAP: try { // ... } catch (ApiException e) { switch (e.getStatusCode()) { case CommonStatusCodes.CANCELED: Log.d(TAG, "One-tap dialog was closed."); // Don't re-prompt the user. showOneTapUI = false; break; case CommonStatusCodes.NETWORK_ERROR: Log.d(TAG, "One-tap encountered a network error."); // Try again or just ignore. break; default: Log.d(TAG, "Couldn't get credential from result." + e.getLocalizedMessage()); break; } } break; } } }
Kotlin
class YourActivity : AppCompatActivity() { // ... private val REQ_ONE_TAP = 2 // Can be any integer unique to the Activity private var showOneTapUI = true // ... override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQ_ONE_TAP -> { try { // ... } catch (e: ApiException) { when (e.statusCode) { CommonStatusCodes.CANCELED -> { Log.d(TAG, "One-tap dialog was closed.") // Don't re-prompt the user. showOneTapUI = false } CommonStatusCodes.NETWORK_ERROR -> { Log.d(TAG, "One-tap encountered a network error.") // Try again or just ignore. } else -> { Log.d(TAG, "Couldn't get credential from result." + " (${e.localizedMessage})") } } } } } } // ... }
5. איך יוצאים מהחשבון
כשמשתמש יוצא מהאפליקציה שלך, יש לקרוא לשיטה signOut()
של הלקוח ב-One Tap.
קריאה אל signOut()
משביתה את הכניסה האוטומטית עד שהמשתמש נכנס שוב לחשבון.
גם אם אתם לא משתמשים בכניסה אוטומטית, השלב הזה חשוב מבטיחה שכאשר המשתמשים יוצאים מהאפליקציה, מצב האימות של כל גם ממשקי ה-API של Play Services שבהם אתם משתמשים יאופסו.
השלבים הבאים
אם הגדרת את הלקוח One Tap כך לאחזר את פרטי הכניסה של Google, האפליקציה שלך יכול עכשיו לקבל אסימונים מזהים של Google שמייצגים את המשתמשים חשבונות Google. נושאי לימוד איך להשתמש באסימונים האלה בקצה העורפי.
אם אתם תומכים ב'כניסה באמצעות חשבון Google', תוכלו גם להשתמש בלקוח One Tap כדי להוסיף תהליך היצירה של החשבון באפליקציה מתבצע בצורה חלקה יותר.