Connexion à un compte associé pour Android

La connexion avec un compte associé permet d'utiliser la connexion One Tap avec Google pour les utilisateurs qui ont déjà associé leur compte Google à votre service. Cela améliore l'expérience des utilisateurs, car ils peuvent se connecter en un clic, sans avoir à saisir à nouveau leur nom d'utilisateur et leur mot de passe. Cela réduit également le risque que les utilisateurs créent des comptes en double sur votre service.

La connexion avec un compte associé est disponible dans le cadre du flux de connexion One Tap pour Android. Cela signifie que vous n'avez pas besoin d'importer une bibliothèque distincte si la fonctionnalité One Tap est déjà activée dans votre application.

Dans ce document, vous allez apprendre à modifier votre application Android pour qu'elle accepte la connexion par compte associé.

Fonctionnement

  1. Vous acceptez d'afficher les comptes associés lors du flux de connexion avec One Tap.
  2. Si l'utilisateur est connecté à Google et a associé son compte Google à son compte sur votre service, un jeton d'ID est renvoyé pour le compte associé.
  3. L'utilisateur voit une invite de connexion One Tap lui proposant de se connecter à votre service avec son compte associé.
  4. Si l'utilisateur choisit de continuer avec le compte associé, son jeton d'ID est renvoyé à votre application. Vous le comparez au jeton envoyé à votre serveur à l'étape 2 pour identifier l'utilisateur connecté.

Configuration

Pour configurer la connexion par compte associé, configurez votre environnement de développement et votre application.

Configurer l'environnement de développement

Téléchargez les derniers services Google Play sur votre hôte de développement :

  1. Ouvrez le SDK Manager d'Android.
  1. Sous SDK Tools, recherchez services Google Play.

  2. Si l'état de ces packages n'est pas "Installé", sélectionnez-les tous les deux, puis cliquez sur Installer les packages.

Configurer votre application

  1. Dans votre fichier build.gradle au niveau du projet, ajoutez le dépôt Maven de Google aux sections buildscript et allprojects.

    buildscript {
        repositories {
            google()
        }
    }
    
    allprojects {
        repositories {
            google()
        }
    }
    
  2. Ajoutez les dépendances de l'API "Associer à Google" au fichier Gradle de votre module au niveau de l'application, qui est généralement app/build.gradle :

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

Modifier votre application Android pour qu'elle accepte la connexion avec un compte associé

À la fin du flux de connexion avec un compte associé, un jeton d'ID est renvoyé à votre application. L'intégrité du jeton d'ID doit être vérifiée avant de connecter l'utilisateur.

L'exemple de code suivant détaille les étapes à suivre pour récupérer et valider le jeton d'ID, puis connecter l'utilisateur.

  1. Créer une activité pour recevoir le résultat de l'intent de connexion

    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. Créer la requête de connexion

    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. Lancer l'intent en attente de connexion

    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);
    });
    

Vérifier l'intégrité du jeton d'ID

Utiliser une bibliothèque cliente des API Google

Nous vous recommandons d'utiliser la bibliothèque cliente des API Google pour Java pour valider les jetons d'ID Google dans un environnement de production.

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.");
  }

La méthode GoogleIdTokenVerifier.verify() vérifie la signature JWT, la revendication aud, la revendication iss et la revendication exp.

Si vous devez valider que le jeton d'ID représente un compte d'organisation Google Workspace ou Cloud, vous pouvez vérifier la revendication hd en vérifiant le nom de domaine renvoyé par la méthode Payload.getHostedDomain().