Permite que los usuarios accedan con sus credenciales guardadas

Usa el cliente de acceso con One Tap para solicitar permiso al usuario para recuperar una de las credenciales que usaron antes para acceder a tu aplicación. Estos las credenciales pueden ser una Cuenta de Google o una combinación de nombre de usuario y contraseña que guardaron con Google usando Chrome, Autocompletar de Android o Smart Lock para Contraseñas.

IU de acceso con un solo toque

Cuando las credenciales se recuperan de forma correcta, puedes usarlas para evitar inconvenientes permitir que el usuario acceda a tu app.

Si el usuario no guardó ninguna credencial, no se presenta ninguna IU, y puedes brindar la experiencia normal cuando no accedes a tu cuenta.

¿Dónde debo usar el acceso con One Tap?

Si tu app requiere que los usuarios accedan, muestra la IU de One Tap cuando accedas. en la pantalla. Esto puede ser útil incluso si ya tienes una cuenta de "Acceder con Google" : debido a que la IU de One Tap se puede configurar para que muestre solo las credenciales del antes de acceder, puede ser un recordatorio para los usuarios que acceder cómo lo hizo la última vez y evitar que accidentalmente crear cuentas nuevas con tu app.

Si el acceso es opcional en tu app, considera usar el acceso con One Tap en cualquier que tiene una experiencia mejorada con el acceso. Por ejemplo, si los usuarios pueden explorar contenido con la app sin acceder a ella, pero solo puede publicar comentarios o agregar contenido artículos a un carrito de compras después de acceder, ese sería un contexto razonable para acceso con One Tap.

Las apps de acceso opcional también deben usar el acceso con One Tap en sus pantallas de acceso. por los motivos mencionados anteriormente.

Antes de comenzar

1. Configura el cliente de acceso con One Tap

Puedes configurar el cliente de acceso con One Tap para que los usuarios accedan con los contraseñas, Cuentas de Google guardadas o cualquiera de ellas. (Se recomienda admitir ambos para habilitar la creación de cuentas con un solo toque para usuarios nuevos y el acceso automático o con un solo toque para tantos usuarios recurrentes como sea posible).

Si tu app usa el acceso basado en contraseña, usa setPasswordRequestOptions() para habilitar solicitudes de credenciales de contraseñas.

Si tu app usa el Acceso con Google, usa setGoogleIdTokenRequestOptions() para habilita y configura las solicitudes de token de ID de Google:

  • Establece el ID de cliente del servidor como el ID que creaste en las APIs de Google. Console. Ten en cuenta que este es el ID de cliente de tu servidor, no tu ID de cliente de Android.

  • Configurar el cliente para filtrar por cuentas autorizadas Cuando habilites esta función , el cliente de One Tap solo solicita a los usuarios que accedan a tu app con Cuentas de Google que ya usaron en el pasado. Esto puede ayudar a los usuarios a firmar correctamente cuando no están seguros de si ya tienen una cuenta o de qué Cuenta de Google que usaron y evita que los usuarios creen accidentalmente con tu app.

  • Si quieres que los usuarios accedan automáticamente cuando sea posible, habilita la función. con setAutoSelectEnabled(). El acceso automático es posible cuando la se cumplen los siguientes criterios:

    • El usuario tiene exactamente una credencial guardada para tu app. Es decir, una contraseña guardada o una Cuenta de Google guardada.
    • El usuario no inhabilitó el acceso automático en la configuración de su Cuenta de Google.
  • Si bien es opcional, te recomendamos que consideres usar un nonce para para mejorar la seguridad de acceso y evitar ataques de repetición. Usa setNonce para incluir un nonce en cada solicitud. Consulta las Cómo obtener un nonce para obtener sugerencias y detalles adicionales sobre cómo generar 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. Cómo buscar un usuario que haya accedido

Si un usuario que accedió a su cuenta o un usuario que salió de su cuenta pueden usar tu Actividad, revisa el estado del usuario antes de mostrar la IU de acceso con One Tap.

También debes hacer un seguimiento de si el usuario ya rechazó su uso. para acceder con One Tap, ya sea cerrando el mensaje o presionando fuera de él. Esto puede debe ser tan simple como una propiedad booleana de tu actividad. (Consulta Cómo dejar de mostrar la IU de One Tap a continuación).

3. Muestra la IU de acceso con One Tap

Si el usuario no accedió y aún no rechazó el uso del acceso con One Tap, haz lo siguiente: llama al método beginSignIn() del objeto del cliente y adjunta objetos de escucha al Se muestra Task. Por lo general, las apps hacen esto en el método onCreate() de la actividad. o después de las transiciones de pantalla cuando usas una arquitectura de actividad única.

El cliente de One Tap llamará al objeto de escucha que detecta el resultado correcto si el usuario guardó alguno credenciales para tu app. En el objeto de escucha que detecta el resultado correcto, obtén el intent pendiente de Task y pásalo a startIntentSenderForResult() para iniciar la IU de acceso con One Tap.

Si el usuario no tiene ninguna credencial guardada, el cliente de One Tap llamará al objeto de escucha de fallas. En este caso, no es necesario que realices ninguna acción: puedes continuar presentar la experiencia sin acceder a la app; Sin embargo, si admites One Tap puede comenzar este flujo aquí para crear una cuenta sin problemas una experiencia fluida a los desarrolladores. Consulta Crear cuentas nuevas con un toque.

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. Cómo controlar la respuesta del usuario

Se informará a tu app la respuesta del usuario al mensaje de acceso con One Tap usando el método onActivityResult() de tu Activity. Si el usuario elige acceder, el resultado será una credencial guardada. Si el usuario rechazó el acceso, cerrando la IU de One Tap o presionando fuera de ella, el resultado se devolverá código RESULT_CANCELED. Tu app debe controlar ambas posibilidades.

Accede con las credenciales recuperadas

Si el usuario eligió compartir las credenciales con tu app, puedes recuperarlas pasando los datos del intent de onActivityResult() al cliente de One Tap getSignInCredentialFromIntent(). La credencial tendrá un valor no nulo La propiedad googleIdToken si el usuario compartió una credencial de la Cuenta de Google con tu app o una propiedad password no nula si el usuario compartió una contraseña guardada.

Usa la credencial para autenticar con el backend de tu app.

  • Si se recuperó un par de nombre de usuario y contraseña, úsalos para acceder con la misma como lo harías si el usuario las hubiera proporcionado manualmente.
  • Si se recuperaron las credenciales de la Cuenta de Google, usa el token de ID para autenticarte. con tu backend. Si decidiste usar un nonce para evitar la repetición verificar el valor de la respuesta en tu servidor de backend. Consulta Autentica con un backend mediante tokens de 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) {
                    // ...
                }
            }
        }
    }
    // ...
}

Dejar de mostrar la IU de One Tap

Si el usuario rechazó el acceso, la llamada a getSignInCredentialFromIntent() arrojará una ApiException con un código de estado CommonStatusCodes.CANCELED. Cuando esto sucede, debes inhabilitar temporalmente la IU de acceso con One Tap para que no molestes a tus usuarios con mensajes repetidos. Con el siguiente ejemplo, se logra esto estableciendo una propiedad en la actividad, que usa para determinar ofrecer al usuario acceso con One Tap Sin embargo, también puedes guardar un valor en SharedPreferences o usa algún otro método.

Es importante que implementes tu propio límite de frecuencia de mensajes de acceso con One Tap. De lo contrario, y un usuario cancela varios mensajes seguidos, el cliente de One Tap no solicitará permiso al usuario durante las próximas 24 horas.

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. Controla la salida

Cuando un usuario salga de tu app, llama al método signOut() del cliente de One Tap. Si llamas a signOut(), se inhabilita el acceso automático hasta que el usuario vuelva a acceder.

Incluso si no usas el acceso automático, este paso es importante garantiza que, cuando los usuarios salgan de tu app, el estado de autenticación de cualquier También se restablecerán las APIs de los Servicios de Play que uses.

Próximos pasos

Si configuraste el cliente One Tap para recuperar credenciales de Google, tu app ahora puedes obtener tokens de ID de Google que representan las claves Cuentas de Google. Aprendizaje cómo puedes usar estos tokens en el backend

Si admites Acceso con Google, también puedes usar el cliente de One Tap para agregar flujos de creación de cuentas sin inconvenientes a tu app.