Consentire agli utenti di accedere con le credenziali salvate

Utilizza il client di accesso One Tap per richiedere l'autorizzazione all'utente per recuperare una delle credenziali usate in precedenza per accedere alla tua app. Questi le credenziali possono essere un Account Google o una combinazione nome utente-password. che ha salvato su Google utilizzando Chrome, la compilazione automatica di Android o Smart Lock per Password.

UI di accesso con un tocco

Una volta recuperate correttamente le credenziali, puoi utilizzarle per semplificare l'operazione far accedere l'utente alla tua app.

Se l'utente non ha salvato alcuna credenziale, non viene visualizzata alcuna UI e per offrire la tua normale esperienza di disconnessione.

Dove dovrei usare l'accesso One Tap?

Se la tua app richiede l'accesso agli utenti, visualizza l'UI One Tap al momento dell'accesso schermo. Questa opzione può essere utile anche se hai già un account "Accedi con Google" Poiché l'interfaccia utente One Tap può essere configurata in modo da mostrare solo le credenziali in precedenza, può essere un promemoria per gli utenti che raramente accedere con l'ultima volta che ha eseguito l'accesso ed evitare che i dati vengano accidentalmente creando nuovi account con la tua app.

Se l'accesso è facoltativo per la tua app, valuta la possibilità di utilizzare l'accesso One Tap su qualsiasi una schermata che offre un'esperienza migliorata eseguendo l'accesso. Ad esempio, se gli utenti possono sfoglia i contenuti con l'app senza eseguire l'accesso, ma può solo pubblicare commenti o aggiungere articoli in un carrello degli acquisti dopo aver effettuato l'accesso, potrebbe essere un buon contesto per Accesso One Tap.

Anche le app facoltative di accesso devono usare l'accesso One Tap nelle schermate di accesso. per i motivi indicati sopra.

Prima di iniziare

1. Configura il client di accesso One Tap

Puoi configurare il client di accesso One Tap per consentire agli utenti di accedere con password, Account Google salvati o entrambi. (Si consiglia di supportarli entrambi, attivare la creazione di account con un solo tocco per i nuovi utenti e l'accesso automatico o con un solo tocco per il maggior numero possibile di utenti di ritorno).

Se la tua app usa l'accesso basato su password, usa setPasswordRequestOptions() per abilitare le richieste di credenziali per la password.

Se la tua app utilizza Accedi con Google, usa setGoogleIdTokenRequestOptions() per attivare e configurare le richieste di token ID Google:

  • Imposta l'ID client server sull'ID che hai creato nelle API di Google. Google Cloud. Tieni presente che questo è l'ID client del server, non il tuo ID client Android.

  • Configura il client per filtrare in base agli account autorizzati. Se attivi questa opzione, , il client One Tap chiede agli utenti di accedere all'app soltanto con Account Google già utilizzati in passato. Così facendo puoi aiutare gli utenti ad accedere correttamente quando non sono sicuri di avere già un account o di quale l'Account Google usato e impedisce agli utenti di crearne accidentalmente nuovi account con la tua app.

  • Se vuoi consentire agli utenti di accedere automaticamente, quando possibile, abilita la funzionalità con setAutoSelectEnabled(). L'accesso automatico è possibile quando vengono soddisfatti i seguenti criteri:

    • L'utente ha una sola credenziale salvata per la tua app. In altre parole, uno salvato una password o un Account Google salvato.
    • L'utente non ha disattivato l'accesso automatico nel suo Impostazioni dell'Account Google.
  • Sebbene sia facoltativo, consigliamo vivamente di utilizzare un nonce per migliorare la sicurezza dell'accesso ed evitare attacchi di ripetizione. Utilizza le funzionalità di setNonce per includere un nonce in ogni richiesta. Vedi SafetyNet Ottenere un nonce per suggerimenti e ulteriori dettagli sulla generazione di un nonce.

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. Verificare se un utente ha eseguito l'accesso

Se la tua Attività può essere utilizzata da un utente che ha eseguito l'accesso o che non ha eseguito l'accesso, controlla lo stato dell'utente prima di visualizzare l'UI di accesso One Tap.

Devi anche monitorare se l'utente ha già rifiutato di utilizzare Accedi con One Tap chiudendo il messaggio o toccandolo all'esterno. Questo può semplice come una proprietà booleana dell'attività. (Vedi Interrompere la visualizzazione dell'UI di One Tap di seguito.)

3. Visualizzare l'interfaccia utente di accesso One Tap

Se l'utente non ha eseguito l'accesso e non ha già rifiutato di utilizzare l'accesso One Tap, chiama il metodo beginSignIn() dell'oggetto client e collega i listener al Task che restituisce. In genere le app lo fanno nel metodo onCreate() dell'Attività o dopo le transizioni sullo schermo quando viene usata un'architettura ad attività singola.

Il client One Tap chiamerà l'ascoltatore di esito positivo se l'utente ha salvato delle le credenziali dell'app. Nel listener riuscito, ottieni l'intent in sospeso da il risultato di Task e passalo a startIntentSenderForResult() per avviare UI di accesso con un tocco.

Se l'utente non dispone di credenziali salvate, il client One Tap chiamerà il listener di errori. In questo caso, non è necessaria alcuna azione: puoi semplicemente continuare che presenta l'esperienza di accesso dell'app senza aver eseguito l'accesso. Tuttavia, se supporti One Tap registrati, puoi avviare la procedura qui per creare facilmente l'account un'esperienza senza intervento manuale. Vedi Creare nuovi account con un tocco.

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. Gestire la risposta dell'utente

La risposta dell'utente alla richiesta di accesso One Tap verrà segnalata alla tua app utilizzando il metodo onActivityResult() delle tue attività. Se l'utente sceglie di accedere, il risultato sarà una credenziale salvata. Se l'utente ha rifiutato di accedere, chiudendo l'interfaccia utente di One Tap o toccandola all'esterno, il risultato verrà restituito con codice RESULT_CANCELED. La tua app deve gestire entrambe le possibilità.

Accedi con le credenziali recuperate

Se l'utente ha scelto di condividere le credenziali con la tua app, puoi recuperarle tramite è stato trasferito i dati sull'intent da onActivityResult() all'account del cliente One Tap Metodo getSignInCredentialFromIntent(). La credenziale avrà un valore diverso da null Proprietà googleIdToken se l'utente ha condiviso la credenziale di un Account Google con la tua app o una proprietà password diversa da null se l'utente ha condiviso una password salvata.

Usa la credenziale per eseguire l'autenticazione con il backend dell'app.

  • Se è stata recuperata una coppia nome utente e password, utilizzali per accedere allo stesso come faresti se l'utente li avesse forniti manualmente.
  • Se le credenziali dell'Account Google sono state recuperate, utilizza il token ID per l'autenticazione con il tuo backend. Se hai scelto di utilizzare un nonce per evitare la riproduzione il valore della risposta sul tuo server di backend. Consulta Esegui l'autenticazione con un backend utilizzando token ID.

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

Interrompere la visualizzazione dell'UI di One Tap

Se l'utente ha rifiutato di accedere, la chiamata al numero getSignInCredentialFromIntent() restituirà un ApiException con il codice di stato CommonStatusCodes.CANCELED. In questi casi, devi disattivare temporaneamente l'interfaccia utente di accesso One Tap per Non infastidire gli utenti con richieste ripetute. L'esempio seguente consente di questo mediante l'impostazione di una proprietà nell'attività, che utilizza per determinare se per offrire all'utente l'accesso One Tap; ma puoi anche salvare un valore SharedPreferences o utilizza un altro metodo.

È importante implementare la limitazione di frequenza delle richieste di accesso One Tap. In caso contrario, e un utente annulla diverse richieste di seguito, il client One Tap all'utente non verrà inviata alcuna richiesta per le prossime 24 ore.

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. Gestire la disconnessione

Quando un utente si disconnette dalla tua app, chiama il metodo signOut() del client One Tap. La chiamata di signOut() disabilita l'accesso automatico fino a quando l'utente non accede di nuovo.

Anche se non utilizzi l'accesso automatico, questo passaggio è importante perché assicura che, quando gli utenti escono dalla tua app, lo stato dell'autenticazione Anche le API di Play Services che utilizzi vengono reimpostate.

Passaggi successivi

Se hai configurato il client One Tap per recuperare le credenziali Google, la tua app ora può ottenere token ID Google che rappresentano i token Account Google. Impara come puoi usare questi token sul backend.

Se supporti Accedi con Google, puoi utilizzare anche il client One Tap per aggiungere la creazione di account fluida nella tua app.