Acceso a una cuenta vinculada para Android

El Acceso con cuentas vinculadas habilita el Acceso con One Tap con Google para los usuarios que ya tienen su Cuenta de Google vinculada a tu servicio. Esto mejora la experiencia de los usuarios, ya que pueden acceder con un solo clic, sin volver a ingresar su nombre de usuario y contraseña. También reduce las probabilidades de que los usuarios creen cuentas duplicadas en tu servicio.

El acceso con la cuenta vinculada está disponible como parte del flujo de acceso con One Tap para Android. Esto significa que no es necesario que importes una biblioteca separada si tu app ya tiene habilitada la función de One Tap.

En este documento, aprenderás a modificar tu app para Android para que admita el acceso con cuentas vinculadas.

Cómo funciona

  1. Habilitas la opción para mostrar las cuentas vinculadas durante el flujo de acceso con One Tap.
  2. Si el usuario accedió a Google y vinculó su Cuenta de Google con su cuenta en tu servicio, se devolverá un token de ID para la cuenta vinculada.
  3. Se le muestra al usuario un mensaje de acceso con One Tap con una opción para acceder a tu servicio con su cuenta vinculada.
  4. Si el usuario elige continuar con la cuenta vinculada, se devolverá el token de ID del usuario a tu app. Debes comparar este token con el token que se envió a tu servidor en el paso 2 para identificar al usuario conectado.

Configuración

Configura tu entorno de desarrollo

Obtén los Servicios de Google Play más recientes en tu host de desarrollo:

  1. Abre el SDK Manager de Android.
  1. En herramientas del SDK, busca Servicios de Google Play.

  2. Si el estado de estos paquetes no es Installed, selecciónalos y haz clic en Install Packages.

Cómo configurar tu app

  1. En tu archivo build.gradle de nivel de proyecto, incluye el repositorio de Maven de Google en las secciones buildscript y allprojects.

    buildscript {
        repositories {
            google()
        }
    }
    
    allprojects {
        repositories {
            google()
        }
    }
    
  2. Agrega las dependencias para la API de "Vincular con Google" al archivo Gradle a nivel de la app de tu módulo, que suele ser app/build.gradle:

    dependencies {
      implementation 'com.google.android.gms:play-services-auth:21.3.0'
    }
    

Modifica tu app para Android para admitir el Acceso con cuentas vinculadas

Al final del flujo de acceso con la Cuenta vinculada, se devuelve un token de ID a tu app. Se debe verificar la integridad del token de ID antes de acceder al usuario.

En la siguiente muestra de código, se detallan los pasos para recuperar y verificar el token de ID y, luego, hacer que el usuario acceda.

  1. Crea una actividad para recibir el resultado del intent de acceso

    Kotlin

      private val activityResultLauncher = registerForActivityResult(
        ActivityResultContracts.StartIntentSenderForResult()) { result ->
        if (result.resultCode == RESULT_OK) {
          try {
            val signInCredentials = Identity.signInClient(this)
                                    .signInCredentialFromIntent(result.data)
            // Review the Verify the integrity of the ID token section for
            // details on how to verify the ID token
            verifyIdToken(signInCredential.googleIdToken)
          } catch (e: ApiException) {
            Log.e(TAG, "Sign-in failed with error code:", e)
          }
        } else {
          Log.e(TAG, "Sign-in failed")
        }
      }
    

    Java

      private final ActivityResultLauncher<IntentSenderResult>
        activityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartIntentSenderForResult(),
        result -> {
        If (result.getResultCode() == RESULT_OK) {
            try {
              SignInCredential signInCredential = Identity.getSignInClient(this)
                             .getSignInCredentialFromIntent(result.getData());
              verifyIdToken(signInCredential.getGoogleIdToken());
            } catch (e: ApiException ) {
              Log.e(TAG, "Sign-in failed with error:", e)
            }
        } else {
            Log.e(TAG, "Sign-in failed")
        }
    });
    
  2. Crea la solicitud de acceso

    Kotlin

    private val tokenRequestOptions =
    GoogleIdTokenRequestOptions.Builder()
      .supported(true)
      // Your server's client ID, not your Android client ID.
      .serverClientId(getString("your-server-client-id")
      .filterByAuthorizedAccounts(true)
      .associateLinkedAccounts("service-id-of-and-defined-by-developer",
                               scopes)
      .build()
    

    Java

     private final GoogleIdTokenRequestOptions tokenRequestOptions =
         GoogleIdTokenRequestOptions.Builder()
      .setSupported(true)
      .setServerClientId("your-service-client-id")
      .setFilterByAuthorizedAccounts(true)
      .associateLinkedAccounts("service-id-of-and-defined-by-developer",
                                scopes)
      .build()
    
  3. Inicia el intent pendiente de acceso

    Kotlin

     Identity.signInClient(this)
        .beginSignIn(
      BeginSignInRequest.Builder()
        .googleIdTokenRequestOptions(tokenRequestOptions)
      .build())
        .addOnSuccessListener{result ->
          activityResultLauncher.launch(result.pendingIntent.intentSender)
      }
      .addOnFailureListener {e ->
        Log.e(TAG, "Sign-in failed because:", e)
      }
    

    Java

     Identity.getSignInClient(this)
      .beginSignIn(
        BeginSignInRequest.Builder()
          .setGoogleIdTokenRequestOptions(tokenRequestOptions)
          .build())
      .addOnSuccessListener(result -> {
        activityResultLauncher.launch(
            result.getPendingIntent().getIntentSender());
    })
    .addOnFailureListener(e -> {
      Log.e(TAG, "Sign-in failed because:", e);
    });
    

Verifica la integridad del token de ID

Usa una biblioteca cliente de la API de Google

Usar la biblioteca cliente de la API de Google para Java es la forma recomendada de validar tokens de ID de Google en un entorno de producción.

Java

  import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
  import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
  import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;

  ...

  GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
      // Specify the CLIENT_ID of the app that accesses the backend:
      .setAudience(Collections.singletonList(CLIENT_ID))
      // Or, if multiple clients access the backend:
      //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
      .build();

  // (Receive idTokenString by HTTPS POST)

  GoogleIdToken idToken = verifier.verify(idTokenString);
  if (idToken != null) {
    Payload payload = idToken.getPayload();

    // Print user identifier
    String userId = payload.getSubject();
    System.out.println("User ID: " + userId);

    // Get profile information from payload
    String email = payload.getEmail();
    boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
    String name = (String) payload.get("name");
    String pictureUrl = (String) payload.get("picture");
    String locale = (String) payload.get("locale");
    String familyName = (String) payload.get("family_name");
    String givenName = (String) payload.get("given_name");

    // Use or store profile information
    // ...

  } else {
    System.out.println("Invalid ID token.");
  }

El método GoogleIdTokenVerifier.verify() verifica la firma del JWT, el reclamo aud, el reclamo iss y el reclamo exp.

Si necesitas validar que el token de ID representa una cuenta de organización de Google Workspace o Cloud, puedes verificar el reclamo hd. Para ello, consulta el nombre de dominio que devuelve el método Payload.getHostedDomain().