Jeśli obsługujesz logowanie się przez konta Google, możesz użyć klienta logowania jednym dotknięciem, aby umożliwić użytkownikom bezproblemowe tworzenie kont i nigdy nie wycofywać ich z kontekstu Twojej aplikacji.
Gdy wyświetlisz interfejs One Tap, użytkownicy zostaną poproszeni o utworzenie nowego konta w aplikacji za pomocą jednego z kont Google na urządzeniu. Jeśli użytkownik zdecyduje się kontynuować, otrzymasz token tożsamości z podstawowymi informacjami profilowymi (imieniem i nazwiskiem, zdjęciem profilowym i zweryfikowanym adresem e-mail), których możesz użyć do utworzenia nowego konta.
Wdrażanie konta jednym dotknięciem składa się z 2 etapów:
- Integracja klienta One Tap z aplikacją, co opisano na tej stronie. Działa to w większości tak samo jak w logowaniu się jednym dotknięciem, ale występują pewne różnice w konfiguracji.
- Dodanie do backendu możliwości tworzenia kont użytkowników na podstawie tokenów identyfikatorów Google, co zostało omówione w sekcji Używanie tokenów tożsamości w backendzie.
Gdzie mogę korzystać z rejestracji jednym dotknięciem?
Jeśli chodzi o możliwość rejestracji jednym dotknięciem, warto zrobić to w kontekście, gdy trzeba będzie zalogować się na konto, żeby włączyć nowe funkcje. Najpierw spróbuj zalogować użytkownika za pomocą zapisanych danych logowania. Jeśli nie znajdziesz żadnych zapisanych danych logowania, zaproponuj utworzenie nowego konta dla użytkownika.
Zanim zaczniesz
Skonfiguruj projekt w konsoli interfejsów API Google i projekt Androida w sposób opisany w artykule Pierwsze kroki z logowaniem jednym dotknięciem.
1. Konfigurowanie klienta One Tap
Aby skonfigurować klienta One Tap do tworzenia kont:
- Nie włączaj żądań danych logowania do haseł. (Rejestracja jednym dotknięciem jest możliwa tylko przy uwierzytelnianiu za pomocą tokenów).
Włącz żądania tokena tożsamości Google za pomocą ustawień
setGoogleIdTokenRequestOptions()
i tych ustawień:- Ustaw identyfikator klienta serwera na identyfikator utworzony w konsoli interfejsów API Google. Pamiętaj, że jest to identyfikator klienta Twojego serwera, a nie identyfikatora klienta Androida.
- Skonfiguruj klienta w taki sposób, aby wyświetlał wszystkie konta Google na urządzeniu – czyli nie filtruj według autoryzowanych kont.
- Opcjonalnie możesz też poprosić o zweryfikowany numer telefonu dla tego konta.
Java
public class YourActivity extends AppCompatActivity { // ... private SignInClient oneTapClient; private BeginSignInRequest signUpRequest; @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); oneTapClient = Identity.getSignInClient(this); signUpRequest = BeginSignInRequest.builder() .setGoogleIdTokenRequestOptions(GoogleIdTokenRequestOptions.builder() .setSupported(true) // Your server's client ID, not your Android client ID. .setServerClientId(getString(R.string.your_web_client_id)) // Show all accounts on the device. .setFilterByAuthorizedAccounts(false) .build()) .build(); // ... } }
Kotlin
class YourActivity : AppCompatActivity() { // ... private lateinit var oneTapClient: SignInClient private lateinit var signUpRequest: BeginSignInRequest override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) oneTapClient = Identity.getSignInClient(this) signUpRequest = BeginSignInRequest.builder() .setGoogleIdTokenRequestOptions( BeginSignInRequest.GoogleIdTokenRequestOptions.builder() .setSupported(true) // Your server's client ID, not your Android client ID. .setServerClientId(getString(R.string.your_web_client_id)) // Show all accounts on the device. .setFilterByAuthorizedAccounts(false) .build()) .build() // ... } // ... }
2. Śledzenie anulowania transakcji jednym dotknięciem w interfejsie użytkownika
Sprawdzaj, czy użytkownik odmówił już rejestracji jednym dotknięciem, zamykając potwierdzenie lub klikając poza nim. Może to być tak proste jak właściwość wartości logicznej aktywności. (patrz sekcja Zatrzymywanie wyświetlania interfejsu jednym dotknięciem poniżej).
3. Wyświetl interfejs rejestracji jednym dotknięciem
Jeśli użytkownik nie odmówił utworzenia nowego konta za pomocą jednego dotknięcia, wywołaj metodę beginSignIn()
obiektu klienta i dołącz detektory do zwróconego obiektu Task
. Aplikacje zwykle robią ten krok, gdy żądanie logowania jednym dotknięciem nie znajduje żadnych zapisanych danych logowania, czyli w odbiorniku błędów logowania.
Klient One Tap wywoła detektor sukcesu, jeśli użytkownik ma na urządzeniu skonfigurowane co najmniej jedno konto Google. W detektorze sukcesu pobierz oczekującą intencję z wyniku Task
i przekaż ją do startIntentSenderForResult()
, aby uruchomić interfejs jednym dotknięciem.
Jeśli użytkownik nie ma żadnych kont Google na urządzeniu, klient One Tap wywoła detektor błędów. W takim przypadku nie musisz nic robić: możesz po prostu dalej prezentować aplikację jako niezalogowany użytkownik, a użytkownik może zarejestrować się w zwykły sposób, korzystając z normalnego procesu tworzenia konta.
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 Google Accounts found. Just continue presenting the signed-out UI.
Log.d(TAG, e.getLocalizedMessage());
}
});
Kotlin
oneTapClient.beginSignIn(signUpRequest)
.addOnSuccessListener(this) { result ->
try {
startIntentSenderForResult(
result.pendingIntent.intentSender, REQ_ONE_TAP,
null, 0, 0, 0)
} catch (e: IntentSender.SendIntentException) {
Log.e(TAG, "Couldn't start One Tap UI: ${e.localizedMessage}")
}
}
.addOnFailureListener(this) { e ->
// No Google Accounts found. Just continue presenting the signed-out UI.
Log.d(TAG, e.localizedMessage)
}
4. Obsługa odpowiedzi użytkownika
Reakcja użytkownika na prośbę o rejestrację jednym dotknięciem zostanie przekazana do aplikacji za pomocą metody onActivityResult()
Twojej aktywności. Jeśli użytkownik zdecyduje się utworzyć konto, wynikiem będzie token tożsamości Google. Jeśli użytkownik odmówił rejestracji, zamykając interfejs jednym dotknięciem lub klikając poza nim, w wyniku pojawi się kod RESULT_CANCELED
. Aplikacja musi obsługiwać obie możliwości.
Tworzenie konta z użyciem tokena identyfikatora Google
Jeśli użytkownik zdecyduje się zarejestrować się za pomocą konta Google, możesz uzyskać dla niego token tożsamości, przekazując dane intencji z onActivityResult()
do metody getSignInCredentialFromIntent()
klienta jednym dotknięciem. Dane logowania będą miały niepustą właściwość googleIdToken
.
Użyj tokena identyfikatora, aby utworzyć konto w backendzie (zobacz Uwierzytelnianie za pomocą backendu przy użyciu tokenów tożsamości) i zalogować użytkownika.
Dane logowania zawierają również wszelkie dodatkowe informacje, które mogły zostać przez Ciebie podane, np. zweryfikowany numer telefonu konta, jeśli jest dostępny.
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(); if (idToken != null) { // Got an ID token from Google. Use it to authenticate // with your backend. Log.d(TAG, "Got ID token."); } } 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 when { idToken != null -> { // Got an ID token from Google. Use it to authenticate // with your backend. Log.d(TAG, "Got ID token.") } else -> { // Shouldn't happen. Log.d(TAG, "No ID token!") } } } catch (e: ApiException) { // ... } } } // ... }
Przestań wyświetlać interfejs jednym dotknięciem
Jeśli użytkownik odmówił zalogowania się, połączenie z numerem getSignInCredentialFromIntent()
spowoduje zgłoszenie błędu ApiException
z kodem stanu CommonStatusCodes.CANCELED
.
W takim przypadku należy tymczasowo zatrzymać wyświetlanie interfejsu logowania jednym dotknięciem, aby nie drażnić użytkowników powtarzającymi się monitami. W poniższym przykładzie pozwala to ustawić w Aktywności jako właściwość, która będzie używana do ustalenia, czy użytkownik powinien skorzystać z logowania jednym dotknięciem. Możesz też zapisać wartość w polu SharedPreferences
lub użyć innej metody.
Ważne jest, aby wdrożyć własne ograniczenie częstotliwości próśb o zalogowanie się jednym dotknięciem. Jeśli tego nie zrobisz, a użytkownik anuluje kilka próśb z rzędu, klient One Tap nie wyświetli użytkownikowi prośby przez następne 24 godziny.
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})") } } } } } } // ... }
Dalsze kroki
Gdy użytkownik dokona rejestracji jednym dotknięciem, otrzymasz token identyfikatora Google, który zawiera podstawowe informacje z profilu: adres e-mail użytkownika, imię i nazwisko oraz adres URL zdjęcia profilowego. W przypadku wielu aplikacji te informacje wystarczą do uwierzytelnienia użytkownika w backendzie i utworzenia nowego konta.
Jeśli do utworzenia konta potrzebujesz dodatkowych informacji – na przykład daty urodzenia użytkownika – wyświetlaj użytkownikowi szczegóły rejestracji, aby poprosić o ich podanie, a następnie wyślij je do backendu, aby dokończyć tworzenie konta.