Ostrzeżenie: te dane są dostarczane zgodnie z Polityką danych użytkownika Google . Zapoznaj się z zasadami i przestrzegaj ich. Niezastosowanie się do tego może spowodować zawieszenie projektu lub zawieszenie konta.

Zaloguj użytkowników przy użyciu ich zapisanych danych uwierzytelniających

Użyj klienta logowania jednym dotknięciem, aby poprosić użytkownika o pozwolenie na pobranie jednego z poświadczeń, których wcześniej użył do zalogowania się do Twojej aplikacji. Te dane uwierzytelniające mogą być kontem Google lub kombinacją nazwy użytkownika i hasła, które zostały zapisane w Google przy użyciu przeglądarki Chrome, autouzupełniania Androida lub funkcji Smart Lock for Passwords.

Interfejs logowania jednym dotknięciem

Po pomyślnym pobraniu poświadczeń możesz ich użyć do bezproblemowego zalogowania użytkownika do aplikacji.

Jeśli użytkownik nie zapisał żadnych poświadczeń, nie jest wyświetlany żaden interfejs użytkownika i możesz zapewnić normalne środowisko wylogowania.

Gdzie mam logować się jednym dotknięciem?

Jeśli Twoja aplikacja wymaga od użytkowników zalogowania się, wyświetl interfejs One Tap na ekranie logowania. Może to być przydatne, nawet jeśli masz już przycisk „Zaloguj się przez Google”: ponieważ interfejs użytkownika One Tap można skonfigurować tak, aby wyświetlał tylko dane uwierzytelniające, których użytkownik używał wcześniej do logowania, może to być przypomnienie dla użytkowników, którzy rzadko się logują sposób, w jaki logowali się po raz ostatni, i zapobiec przypadkowemu tworzeniu nowych kont w Twojej aplikacji.

Jeśli logowanie w Twojej aplikacji jest opcjonalne, rozważ korzystanie z logowania jednym dotknięciem na dowolnym ekranie, na którym można się zalogować. Na przykład, jeśli użytkownicy mogą przeglądać zawartość w Twojej aplikacji po wylogowaniu się, ale mogą tylko publikować komentarze lub dodawać elementy do koszyka po zalogowaniu, który byłby rozsądnym kontekstem dla logowania jednym dotknięciem.

Opcjonalne aplikacje do logowania powinny również korzystać z logowania jednym dotknięciem na swoich ekranach logowania z powodów wymienionych powyżej.

Zanim zaczniesz

1. Skonfiguruj klienta logowania jednym dotknięciem

Możesz skonfigurować klienta logowania jednym dotknięciem tak, aby logował użytkowników przy użyciu zapisanych haseł, zapisanych kont Google lub jednego z nich. (Zalecana jest obsługa obu, aby umożliwić tworzenie kont jednym dotknięciem dla nowych użytkowników oraz automatyczne lub jedno dotknięcie logowania dla jak największej liczby powracających użytkowników).

Jeśli twoje hasło zastosowania aplikacji opartych logowania, użyj setPasswordRequestOptions() , aby włączyć hasło poświadczeń żądań.

Jeśli aplikacja korzysta z Google logowania, użytkowania setGoogleIdTokenRequestOptions() , aby włączyć i skonfigurować Google ID symboliczne wnioski:

  • Ustaw identyfikator klienta serwera do utworzonego w konsoli Google API ID . Pamiętaj, że jest to identyfikator klienta serwera, a nie identyfikator klienta Androida.

  • Skonfiguruj klienta tak, aby filtrował według autoryzowanych kont. Gdy włączysz tę opcję, klient One Tap prosi użytkowników tylko o zalogowanie się do Twojej aplikacji przy użyciu kont Google, z których korzystali już w przeszłości. Może to pomóc użytkownikom w pomyślnym zalogowaniu się, gdy nie są pewni, czy mają już konto lub którego konta Google używali, oraz zapobiec przypadkowemu tworzeniu nowych kont w Twojej aplikacji.

  • Jeśli chcesz się zalogować użytkownikom automatycznie, gdy to możliwe, należy włączyć funkcję z setAutoSelectEnabled() . Automatyczne logowanie jest możliwe, gdy spełnione są następujące kryteria:

    • Użytkownik ma zapisane dokładnie jedno poświadczenie dla Twojej aplikacji. To znaczy jedno zapisane hasło lub jedno zapisane konto Google.
    • Użytkownik nie wyłączył automatycznego logowania w swoich ustawieniach konta Google .
  • Chociaż jest to opcjonalne, zalecamy zdecydowanie rozważyć użycie jednorazy, aby poprawić bezpieczeństwo logowania i uniknąć ataków polegających na powtarzaniu. Użyj setNonce dołączyć identyfikator jednorazowy w każdej życzenie. Zobacz SafetyNet znajduje Uzyskanie nonce punkt na sugestie i dodatkowe szczegóły na generowanie nonce.

Jawa

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. Sprawdź, czy jest zalogowany użytkownik

Jeśli Twoja Aktywność może być używana przez zalogowanego lub wylogowanego użytkownika, sprawdź stan użytkownika przed wyświetleniem interfejsu logowania jednym dotknięciem.

Należy również śledzić, czy użytkownik już odmówił korzystania z logowania jednym dotknięciem, zamykając monit lub stukając poza nim. Może to być tak proste, jak właściwość logiczna Twojej Aktywności. (Patrz Zatrzymanie wyświetlania One Tap UI , poniżej).

3. Wyświetl interfejs logowania jednym dotknięciem

Jeśli użytkownik nie jest zalogowany, a nie już spadła do korzystania z jednego Tap logowania, zadzwoń obiektu klienckiego beginSignIn() metody i dołączyć do słuchaczy Task to powraca. Aplikacje zwykle do tego w aktywności w onCreate() metody lub po przejścia ekranu przy zastosowaniu architektury pojedynczej czynności.

Klient One Tap zadzwoni do odbiornika sukcesu, jeśli użytkownik ma zapisane dane logowania do Twojej aplikacji. W słuchacza sukces, uzyskać oczekiwaniu zamiar z Task wyniku i przekazać go do startIntentSenderForResult() , aby rozpocząć proces logowania UI jednym dotknięciem.

Jeśli użytkownik nie ma żadnych zapisanych poświadczeń, klient One Tap wywoła detektor awarii. W takim przypadku nie jest wymagane żadne działanie: możesz po prostu kontynuować prezentowanie wylogowanego środowiska aplikacji. Jeśli jednak obsługujesz rejestrację One Tap, możesz rozpocząć ten przepływ tutaj, aby bezproblemowo tworzyć konto. Zobacz Tworzenie nowych kont z jednego kranu .

Jawa

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. Obsługuj odpowiedź użytkownika

Odpowiedź autora do One Tap logowania zachęty będą zgłaszane do aplikacji za pomocą swoją aktywność w onActivityResult() metody. Jeśli użytkownik zdecyduje się zalogować, wynikiem będzie zapisane poświadczenie. Jeśli użytkownik zmniejszył się zalogować, albo zamykając One Tap UI lub dotykając go na zewnątrz, wynik powróci z kodem RESULT_CANCELED . Twoja aplikacja musi obsługiwać obie możliwości.

Zaloguj się przy użyciu pobranych danych uwierzytelniających

Jeśli użytkownik wybrał, aby podzielić się z poświadczeniami aplikacji, można pobrać je przekazując dane intencyjny onActivityResult() do klienta jednym kliknięciem za getSignInCredentialFromIntent() metody. Poświadczenia będzie mieć niezerowe googleIdToken nieruchomość, jeśli użytkownik shared poświadczeń konta Google z aplikacji lub niezerowym password własności, jeśli użytkownik shared zapisane hasło.

Użyj poświadczeń, aby uwierzytelnić się za pomocą zaplecza aplikacji.

  • Jeśli pobrano parę nazwy użytkownika i hasła, użyj ich do podpisania w taki sam sposób, jak gdyby użytkownik podał je ręcznie.
  • Jeśli pobrano dane logowania do konta Google, użyj tokena identyfikatora, aby uwierzytelnić się w swoim zapleczu. Jeśli zdecydowałeś się użyć jednorazy, aby uniknąć ataków typu powtórka, sprawdź wartość odpowiedzi na serwerze zaplecza. Zobacz uwierzytelniania backend przy użyciu tokenów identyfikacyjnych .

Jawa

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) {
                    // ...
                }
            }
        }
    }
    // ...
}

Przestań wyświetlać interfejs One Tap

Jeśli użytkownik zmniejszył się zalogować, wywołanie getSignInCredentialFromIntent() wygeneruje ApiException z CommonStatusCodes.CANCELED kodem stanu. W takim przypadku należy tymczasowo wyłączyć interfejs logowania jednym dotknięciem, aby nie denerwować użytkowników powtarzającymi się monitami. Poniższy przykład osiąga to poprzez ustawienie właściwości w działaniu, której używa do określenia, czy oferować użytkownikowi logowanie jednym dotknięciem; Jednakże, można również zapisać wartość do SharedPreferences lub użyć innej metody.

Ważne jest, aby wdrożyć własne ograniczenie szybkości monitów logowania jednym dotknięciem. Jeśli tego nie zrobisz, a użytkownik anuluje kilka monitów z rzędu, klient One Tap nie wyświetli monitu przez następne 24 godziny.

Jawa

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. Obsługa wylogowania

Gdy użytkownik rejestruje się z aplikacji, należy zadzwonić do klienta jednym kliknięciem za signOut() metody. Wywołanie signOut() powoduje wyłączenie automatycznego logowania użytkownika, aż znaki ponownie.

Nawet jeśli nie korzystasz z automatycznego logowania, ten krok jest ważny, ponieważ zapewnia, że ​​gdy użytkownicy wylogują się z aplikacji, stan uwierzytelniania wszystkich używanych interfejsów API usług Play również zostanie zresetowany.

Następne kroki

Jeśli skonfigurowałeś klienta One Tap do pobierania danych logowania Google, Twoja aplikacja może teraz pobierać tokeny Google ID, które reprezentują konta Google Twoich użytkowników. Dowiedz się, jak można wykorzystać te znaki na backend .

Jeśli wsparcie logowania Google, można także użyć klienta Jeden Dotknij, aby dodać tworzenia konta tarcia płynie do swojej aplikacji .