Intégrer le Gestionnaire d'identifiants à la fonctionnalité Se connecter avec Google

Bottom sheet du gestionnaire d'identifiants montrant différentes identités parmi lesquelles choisir.
Figure 1. La boîte de dialogue "Se connecter avec Google" sous forme de bottom sheet après l'intégration avec l'API Gestionnaire d'identifiants.

Ce document explique comment migrer la boîte de dialogue Se connecter avec Google sous forme de bottom sheet de Google Identity Services (GIS) vers l'API Gestionnaire d'identifiants à l'aide de la bibliothèque d'aide de l'ID Google.

Une application qui utilise l'API Gestionnaire d'identifiants est configurée pour présenter à l'utilisateur final une interface utilisateur Android cohérente qui lui permet de faire son choix dans une liste d'options de connexion enregistrées, y compris des comptes avec clé d'accès. Il s'agit de l'API Android recommandée pour consolider différents types d'identifiants et différents fournisseurs. Depuis Android 14, les utilisateurs peuvent également exploiter les gestionnaires de mots de passe tiers grâce à l'API Gestionnaire d'identifiants.

Déclarer des dépendances

Dans le fichier build.gradle de votre module, déclarez les dépendances à l'aide de la dernière version:

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>"
}

Suivez les instructions pour configurer votre projet dans la console Google APIs. Remplacez les conseils sur l'inclusion des dépendances par les instructions mentionnées ci-dessus.

Instancier une requête Google Sign-In

Pour commencer l'implémentation, instanciez une requête Google Sign-In. Utilisez GetGoogleIdOption pour récupérer le jeton d'ID Google d'un utilisateur.

Kotlin

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .build()

Java

GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .build();

Vous devez d'abord appeler l'API avec le paramètre setFilterByAuthorizedAccounts défini sur true. Si aucun identifiant n'est disponible, appelez à nouveau l'API et définissez setFilterByAuthorizedAccounts sur false.

Si vous souhaitez que les utilisateurs soient connectés automatiquement lorsque cela est possible, activez la fonctionnalité avec setAutoSelectEnabled dans votre requête GetGoogleIdOption. La connexion automatique est possible lorsque les conditions suivantes sont remplies :

  • L'utilisateur ne dispose que d'un seul identifiant enregistré pour votre application. Autrement dit, un mot de passe ou un compte Google enregistré.
  • L'utilisateur n'a pas désactivé la connexion automatique dans les paramètres de compte Google.

Pour améliorer la sécurité de la connexion et éviter les attaques par rejeu, utilisez setNonce pour inclure un nonce dans chaque requête. Découvrez comment générer un nonce.

Kotlin

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

Java

GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(SERVER_CLIENT_ID)
  .setNonce(<nonce string to use when generating a Google ID token>);
  .build();

Se connecter avec Google

Pour configurer un flux de connexion avec Google, procédez comme suit :

  1. Instanciez GetCredentialRequest et ajoutez l'élément googleIdOption créé ci-dessus pour récupérer les identifiants.
  2. Transmettez cette requête à l'appel getCredential() (Kotlin) ou getCredentialAsync() (Java) pour récupérer les identifiants de l'utilisateur disponibles.
  3. Une fois l'API établie, extrayez CustomCredential, qui contient le résultat des données GoogleIdTokenCredential.
  4. Le type de CustomCredential doit être égal à la valeur de GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL. Convertissez l'objet en GoogleIdTokenCredential à l'aide de la méthode GoogleIdTokenCredential.createFrom.
  5. Si la conversion aboutit, extrayez l'ID de GoogleIdTokenCredential, validez-le et authentifiez les identifiants sur votre serveur.
  6. Si la conversion échoue avec une erreur GoogleIdTokenParsingException, vous devrez peut-être mettre à jour la version de votre bibliothèque Se connecter avec Google.
  7. Récupérez tous les types d'identifiants personnalisés non reconnus.

Kotlin

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

coroutineScope.launch {
  try {
    val result = credentialManager.getCredential(
      request = request,
      context = activityContext,
    )
    handleSignIn(result)
  } catch (e: GetCredentialException) {
    handleFailure(e)
  }
}

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

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

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

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

Java

GetCredentialRequest request = new GetCredentialRequest.Builder()
  .addGetCredentialOption(googleIdOption)
  .build();

// Launch sign in flow and do getCredential Request to retrieve the credentials
credentialManager.getCredentialAsync(
  requireActivity(),
  request,
  cancellationSignal,
  <executor>,
  new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
    @Override
    public void onResult(GetCredentialResponse result) {
      handleSignIn(result);
    }

    @Override
    public void onError(GetCredentialException e) {
      handleFailure(e);
    }
  }
);

public void handleSignIn(GetCredentialResponse result) {
  // Handle the successfully returned credential.
  Credential credential = result.getCredential();

  if (credential instanceof PublicKeyCredential) {
    String responseJson = ((PublicKeyCredential) credential).getAuthenticationResponseJson();
    // Share responseJson i.e. a GetCredentialResponse on your server to validate and authenticate
  } else if (credential instanceof PasswordCredential) {
    String username = ((PasswordCredential) credential).getId();
    String password = ((PasswordCredential) credential).getPassword();
    // Use id and password to send to your server to validate and authenticate
  } else if (credential instanceof CustomCredential) {
    if (GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL.equals(credential.getType())) {
      try {
        // Use googleIdTokenCredential and extract id to validate and
        // authenticate on your server
        GoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(((CustomCredential) credential).getData());
      } catch (GoogleIdTokenParsingException e) {
        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");
  }
}

Bouton "Se connecter avec Google"

Le bouton "Se connecter avec Google" est pris en charge par le Gestionnaire d'identifiants avec la bibliothèque d'aide de l'ID Google la plus récente. Pour déclencher le flux du bouton "Se connecter avec Google", utilisez GetSignInWithGoogleOption au lieu de GetGoogleIdOption, et gérez les GoogleIdTokenCredential comme précédemment.

S'inscrire avec Google

Si aucun résultat n'est renvoyé après avoir défini setFilterByAuthorizedAccounts sur true lors de l'instanciation de la requête GetGoogleIdOption et du transfert à GetCredentialsRequest, cela signifie que la connexion n'est autorisée pour aucun compte. À ce stade, vous devez définir setFilterByAuthorizedAccounts(false) et appeler S'inscrire avec Google.

Kotlin

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

Java

GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(false)
  .setServerClientId(SERVER_CLIENT_ID)
  .build();

Une fois la requête d'inscription Google créée, lancez le flux d'authentification comme indiqué dans la section Se connecter avec Google.

Gérer la déconnexion

Lorsqu'un utilisateur se déconnecte de votre application, appelez la méthode clearCredentialState() de l'API pour effacer l'état actuel des identifiants utilisateur et réinitialiser l'état interne de la connexion.