Autentica usuarios con Acceder con Google

Acceder con Google te ayuda a integrar rápidamente la autenticación de usuarios en tu app para Android. Los usuarios pueden usar su Cuenta de Google para acceder a tu app, dar su consentimiento y compartir de forma segura la información de su perfil con tu app. La biblioteca de Credential Manager de Jetpack para Android facilita esta integración y ofrece una experiencia coherente en todos los dispositivos Android con una sola API.

En este documento, se explica cómo implementar Acceder con Google en apps para Android, cómo configurar la IU del botón de Acceder con Google y cómo configurar experiencias de acceso y registro con un solo toque optimizadas para la app. Para una migración de dispositivos sin problemas, Acceder con Google admite el acceso automático, y su naturaleza multiplataforma en Android, iOS y las plataformas web te ayuda a proporcionar acceso a tu app en cualquier dispositivo. Si usas Firebase Authentication para tu aplicación, puedes obtener más información sobre la integración del Acceso con Google y Credential Manager en su guía Authenticate with Google on Android.

Para configurar el acceso con Google, sigue estos dos pasos principales:

Configura Acceder con Google como una opción para la IU de la hoja inferior de Credential Manager. Se puede configurar para que se le solicite automáticamente al usuario que acceda. Si implementaste contraseñas o llaves de acceso, puedes solicitar todos los tipos de credenciales pertinentes de forma simultánea para que el usuario no tenga que recordar la opción que usó anteriormente para acceder.

Hoja inferior del Administrador de credenciales
Figura 1: La hoja inferior del Administrador de credenciales, IU de selección de credenciales

Agrega el botón de Acceder con Google a la IU de tu app. El botón Acceder con Google ofrece una forma optimizada para que los usuarios usen sus Cuentas de Google existentes para registrarse o acceder a apps para Android. Los usuarios harán clic en el botón Acceder con Google si descartan la IU de la hoja inferior o si desean usar explícitamente su Cuenta de Google para registrarse y acceder. Para los desarrolladores, esto significa una incorporación de usuarios más sencilla y una menor fricción durante el registro.

Animación que muestra el flujo de Acceder con Google
Figura 2: IU del botón de Acceder con Google de Credential Manager

En este documento, se explica cómo integrar el botón y el diálogo de la hoja inferior de Acceder con Google en la API de Credential Manager con la biblioteca auxiliar de ID de Google.

Configura tu proyecto

  1. Abre tu proyecto en o crea uno si aún no tienes uno.
  2. En , asegúrate de que toda la información esté completa y sea precisa.
    1. Asegúrate de que tu app tenga asignados el nombre, el logotipo y la página principal correctos. Estos valores se presentarán a los usuarios en la pantalla de consentimiento de Acceder con Google durante el registro y en la pantalla de Apps y servicios de terceros.
    2. Asegúrate de haber especificado las URLs de la política de privacidad y las condiciones del servicio de tu app.
  3. En , crea un ID de cliente de Android para tu app si aún no tienes uno. Deberás especificar el nombre del paquete y la firma SHA-1 de tu app.
    1. Ve a .
    2. Haz clic en Crear cliente.
    3. Selecciona el tipo de aplicación Android.
  4. En , crea un nuevo ID de cliente de "Aplicación web" si aún no lo hiciste. Por el momento, puedes ignorar los campos "Orígenes de JavaScript autorizados" y "URI de redireccionamiento autorizados". Este ID de cliente se usará para identificar tu servidor de backend cuando se comunique con los servicios de autenticación de Google.
    1. Ve a .
    2. Haz clic en Crear cliente.
    3. Selecciona el tipo Aplicación web.

Cómo declarar dependencias

En el archivo build.gradle de tu módulo, declara dependencias con la versión más reciente del Administrador de credenciales:

dependencies {
  // ... other dependencies
  implementation "androidx.credentials:credentials:<latest version>"
  implementation "androidx.credentials:credentials-play-services-auth:<latest version>"
  implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>"
}

Cómo crear una instancia de una solicitud de acceso con Google

Para comenzar con la implementación, crea una instancia de una solicitud de acceso con Google. Usa GetGoogleIdOption para recuperar el token de ID de Google de un usuario.

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  // nonce string to use when generating a Google ID token
  .setNonce(nonce)
.build()

Primero, verifica si el usuario tiene cuentas que se hayan usado anteriormente para acceder a tu app llamando a la API con el parámetro setFilterByAuthorizedAccounts establecido en true. Los usuarios pueden elegir entre las cuentas disponibles para acceder.

Si no hay Cuentas de Google autorizadas disponibles, se le debe solicitar al usuario que se registre con cualquiera de sus cuentas disponibles. Para ello, llama a la API de nuevo y establece setFilterByAuthorizedAccounts en false. Obtén más información para registrarte.

Habilita el acceso automático para los usuarios recurrentes (recomendado)

Los desarrolladores deben habilitar el acceso automático para los usuarios que se registren con su cuenta única. Esto proporciona una experiencia fluida en todos los dispositivos, especialmente durante la migración de dispositivos, en la que los usuarios pueden recuperar rápidamente el acceso a su cuenta sin volver a ingresar las credenciales. Para los usuarios, esto elimina la fricción innecesaria cuando ya habían accedido anteriormente.

Para habilitar el acceso automático, usa setAutoSelectEnabled(true). El acceso automático solo es posible cuando se cumplen los siguientes criterios:

  • Hay una sola credencial que coincide con la solicitud, que puede ser una Cuenta de Google o una contraseña, y esta credencial coincide con la cuenta predeterminada en el dispositivo con Android.
  • El usuario no salió de la cuenta de forma explícita.
  • El usuario no inhabilitó el acceso automático en la configuración de su Cuenta de Google.
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  // nonce string to use when generating a Google ID token
  .setNonce(nonce)
.build()

Recuerda controlar correctamente el cierre de sesión cuando implementes el acceso automático, de modo que los usuarios siempre puedan elegir la cuenta adecuada después de salir explícitamente de tu app.

Cómo establecer un nonce para mejorar la seguridad

Para mejorar la seguridad de acceso y evitar ataques de repetición, agrega setNonce para incluir un nonce en cada solicitud. Obtén más información para generar un nonce.

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  // nonce string to use when generating a Google ID token
  .setNonce(nonce)
.build()

Crea el flujo de Acceder con Google

Los pasos para configurar un flujo de Acceder con Google son los siguientes:

  1. Crea una instancia de GetCredentialRequest y, luego, agrega el elemento googleIdOption creado anteriormente con addCredentialOption() para recuperar las credenciales.
  2. Pasa esta solicitud a la llamada a getCredential() (Kotlin) o a getCredentialAsync() (Java) para recuperar las credenciales disponibles del usuario.
  3. Una vez que la API funcione de forma correcta, extrae el objeto CustomCredential que contiene el resultado de los datos de GoogleIdTokenCredential.
  4. El tipo de CustomCredential debe ser igual al valor de GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL. Convierte el objeto en un GoogleIdTokenCredential con el método GoogleIdTokenCredential.createFrom.
  5. Si la conversión se realiza correctamente, extrae el ID de GoogleIdTokenCredential, valídalo y autentica la credencial en tu servidor.

  6. Si la conversión falla con una GoogleIdTokenParsingException, es posible que debas actualizar la versión de la biblioteca de Acceder con Google.

  7. Detecta cualquier tipo de credencial personalizada no reconocido.

val request: GetCredentialRequest = GetCredentialRequest.Builder()
  .addCredentialOption(googleIdOption)
  .build()

coroutineScope {
  try {
    val result = credentialManager.getCredential(
      request = request,
      context = activityContext,
    )
    handleSignIn(result)
  } catch (e: GetCredentialException) {
    // Handle failure
  }
}
fun handleSignIn(result: GetCredentialResponse) {
  // Handle the successfully returned credential.
  val credential = result.credential
  val responseJson: String

  when (credential) {

    // Passkey credential
    is PublicKeyCredential -> {
      // Share responseJson such as a GetCredentialResponse to your server to validate and
      // authenticate
      responseJson = credential.authenticationResponseJson
    }

    // Password credential
    is PasswordCredential -> {
      // Send ID and password to your server to validate and authenticate.
      val username = credential.id
      val password = credential.password
    }

    // GoogleIdToken credential
    is CustomCredential -> {
      if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
        try {
          // Use googleIdTokenCredential and extract the ID to validate and
          // authenticate on your server.
          val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)
          // You can use the members of googleIdTokenCredential directly for UX
          // purposes, but don't use them to store or control access to user
          // data. For that you first need to validate the token:
          // pass googleIdTokenCredential.getIdToken() to the backend server.
          // see [validation instructions](https://developers.google.com/identity/gsi/web/guides/verify-google-id-token)
        } catch (e: GoogleIdTokenParsingException) {
          Log.e(TAG, "Received an invalid google id token response", e)
        }
      } else {
        // Catch any unrecognized custom credential type here.
        Log.e(TAG, "Unexpected type of credential")
      }
    }

    else -> {
      // Catch any unrecognized credential type here.
      Log.e(TAG, "Unexpected type of credential")
    }
  }
}

Cómo activar un flujo del botón de Acceder con Google

Para activar el flujo del botón de Acceder con Google, usa GetSignInWithGoogleOption en lugar de GetGoogleIdOption:

val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder(
  serverClientId = WEB_CLIENT_ID
).setNonce(nonce)
  .build()

Controla el GoogleIdTokenCredential devuelto como se describe en el siguiente ejemplo de código.

fun handleSignInWithGoogleOption(result: GetCredentialResponse) {
  // Handle the successfully returned credential.
  val credential = result.credential

  when (credential) {
    is CustomCredential -> {
      if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
        try {
          // Use googleIdTokenCredential and extract id to validate and
          // authenticate on your server.
          val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)
        } catch (e: GoogleIdTokenParsingException) {
          Log.e(TAG, "Received an invalid google id token response", e)
        }
      }
      else {
        // Catch any unrecognized credential type here.
        Log.e(TAG, "Unexpected type of credential")
      }
    }

    else -> {
      // Catch any unrecognized credential type here.
      Log.e(TAG, "Unexpected type of credential")
    }
  }
}

Una vez que crees una instancia de la solicitud de Acceder con Google, inicia el flujo de autenticación de una manera similar a la que se menciona en la sección Acceder con Google.

Habilita el registro para usuarios nuevos (opción recomendada)

Acceder con Google es la forma más fácil para que los usuarios creen una cuenta nueva con tu app o servicio con solo unos toques.

Si no se encuentran credenciales guardadas (getGoogleIdOption no devuelve ninguna Cuenta de Google), solicita al usuario que se registre. Primero, verifica setFilterByAuthorizedAccounts(true) para ver si existen cuentas usadas anteriormente. Si no se encuentra ninguna, se le pedirá al usuario que se registre con su Cuenta de Google usando setFilterByAuthorizedAccounts(false).

Ejemplo:

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(false)
  .setServerClientId(WEB_CLIENT_ID)
  .build()

Una vez que crees una instancia de la solicitud de Registrarse con Google, inicia el flujo de autenticación. Si los usuarios no quieren usar Acceder con Google para registrarse, considera optimizar tu app para el autocompletado. Una vez que el usuario haya creado una cuenta, considera inscribirlo en las llaves de acceso como paso final para la creación de la cuenta.

Controla el cierre de sesión

Cuando un usuario salga de tu app, llama al método clearCredentialState() de la API para borrar el estado actual de las credenciales del usuario de todos los proveedores de credenciales. Esto notificará a todos los proveedores de credenciales que se debe borrar cualquier sesión de credenciales almacenada para la app determinada.

Es posible que un proveedor de credenciales haya almacenado una sesión de credenciales activa y la use para limitar las opciones de acceso en futuras llamadas de get-credential. Por ejemplo, puede priorizar la credencial activa por sobre cualquier otra credencial disponible. Cuando el usuario salga explícitamente de tu app y para obtener las opciones de acceso integral la próxima vez, debes llamar a esta API para permitir que el proveedor borre cualquier sesión de credenciales almacenada.