Associer plusieurs fournisseurs à un compte

Ce document explique comment associer plusieurs fournisseurs à un seul compte Identity Platform.

Identity Platform utilise un identifiant unique pour identifier les utilisateurs. Cela permet aux utilisateurs de se connecter au même compte avec différents fournisseurs. Par exemple, un utilisateur qui s'est initialement enregistré avec un numéro de téléphone peut associer plus tard son compte Google, puis utiliser l'une des deux méthodes pour se connecter.

Avant de commencer

Ajoutez la compatibilité avec au moins deux fournisseurs d'identité à votre application.

Activer ou désactiver l'association de comptes

Le paramètre d'association de comptes détermine la façon dont Identity Platform gère les utilisateurs tentant de se connecter avec la même adresse e-mail via différents fournisseurs.

  • Associer des comptes qui utilisent la même adresse e-mail : Identity Platform génère une erreur si un utilisateur tente de se connecter avec une adresse e-mail déjà utilisée. Votre application peut détecter cette erreur et associer le nouveau fournisseur à son compte existant.

  • Créer plusieurs comptes pour chaque fournisseur d'identité : un nouveau compte utilisateur Identity Platform est créé chaque fois qu'un utilisateur se connecte avec un fournisseur différent.

Pour choisir un paramètre :

  1. Accédez à la page Paramètres d'Identity Platform dans Cloud Console.

    Accéder à la page Paramètres

  2. Sélectionnez un paramètre sous Association de comptes utilisateur.

  3. Cliquez sur Enregistrer.

Associer les identifiants d'un fournisseur fédéré

Pour associer les identifiants d'un fournisseur fédéré :

  1. Connectez-vous à l'utilisateur avec une méthode ou un fournisseur d'authentification.

  2. Récupérez l'objet de fournisseur qui correspond au fournisseur que vous souhaitez associer au compte de l'utilisateur. Exemple :

    JavaScript

    var googleProvider = new firebase.auth.GoogleAuthProvider();
    var facebookProvider = new firebase.auth.FacebookAuthProvider();
    var twitterProvider = new firebase.auth.TwitterAuthProvider();
    var githubProvider = new firebase.auth.GithubAuthProvider();
  3. Invitez l'utilisateur à se connecter avec le fournisseur que vous souhaitez associer. Vous pouvez soit ouvrir une fenêtre pop-up, soit rediriger la page actuelle. La redirection est plus facile pour les utilisateurs d'appareils mobiles.

    Pour afficher une fenêtre pop-up, appelez linkWithPopup() :

    JavaScript

    auth.currentUser.linkWithPopup(provider).then((result) => {
      // Accounts successfully linked.
      var credential = result.credential;
      var user = result.user;
      // ...
    }).catch((error) => {
      // Handle Errors here.
      // ...
    });

    Pour rediriger la page, commencez par appeler linkWithRedirect() :

    JavaScript

    auth.currentUser.linkWithRedirect(provider)
      .then(/* ... */)
      .catch(/* ... */);

    Une fois l'utilisateur connecté, il est redirigé vers votre application. Ensuite, vous pouvez récupérer le résultat de la connexion en appelant getRedirectResult() :

    JavaScript

    auth.getRedirectResult().then((result) => {
      if (result.credential) {
        // Accounts successfully linked.
        var credential = result.credential;
        var user = result.user;
        // ...
      }
    }).catch((error) => {
      // Handle Errors here.
      // ...
    });

Le compte de l'utilisateur avec le fournisseur fédéré est désormais associé à son compte Identity Platform, et l'utilisateur peut se connecter à l'aide du fournisseur.

Associer des identifiants de messagerie et de mot de passe

Pour ajouter une adresse e-mail et un mot de passe à un compte utilisateur existant, procédez comme suit :

  1. Connectez-vous à l'utilisateur avec une méthode ou un fournisseur d'identité.

  2. Demandez à l'utilisateur de spécifier une adresse e-mail et un mot de passe.

  3. Créez un objet AuthCredential avec l'adresse e-mail et le mot de passe :

    JavaScript

    var credential = firebase.auth.EmailAuthProvider.credential(email, password);
  4. Transmettez l'objet AuthCredential à la méthode linkWithCredential() sur l'utilisateur connecté :

    JavaScript

    auth.currentUser.linkWithCredential(credential)
      .then((usercred) => {
        var user = usercred.user;
        console.log("Account linking success", user);
      }).catch((error) => {
        console.log("Account linking error", error);
      });

Les identifiants d'adresse e-mail et de mot de passe sont désormais associés au compte Identity Platform de l'utilisateur, et celui-ci peut s'en servir pour se connecter.

Gérer les erreurs de compte existant avec un identifiant différent

Si vous avez activé le paramètre Associer les comptes qui utilisent la même adresse e-mail, Identity Platform génère une erreur lorsqu'un utilisateur tente de se connecter à un fournisseur via une adresse e-mail déjà associée avec un compte existant.

Pour gérer cette erreur, invitez l'utilisateur à se connecter avec un compte existant. Appelez ensuite linkWithCredential(), linkWithPopup() ou linkWithRedirect() pour associer le nouveau fournisseur à son compte.

L'exemple suivant montre comment gérer cette erreur lorsqu'un utilisateur tente de se connecter à l'aide de Facebook :

JavaScript

// User tries to sign in with Facebook.
auth.signInWithPopup(new firebase.auth.FacebookAuthProvider()).catch(err => {
  // User's email already exists.
  if (err.code === 'auth/account-exists-with-different-credential') {
    // The pending Facebook credential.
    var pendingCred = err.credential;
    // The provider account's email address.
    var email = err.email;
    // Get the sign-in methods for this email.
    auth.fetchSignInMethodsForEmail(email).then(methods => {
      // If the user has several sign-in methods, the first method
      // in the list will be the "recommended" method to use.
      if (methods[0] === 'password') {
        // TODO: Ask the user for their password.
        // In real scenario, you should handle this asynchronously.
        var password = promptUserForPassword();
        auth.signInWithEmailAndPassword(email, password).then(result => {
          return result.user.linkWithCredential(pendingCred);
        }).then(() => {
          // Facebook account successfully linked to the existing user.
          goToApp();
        });
        return;
      }
      // All other cases are external providers.
      // Construct provider object for that provider.
      // TODO: Implement getProviderForProviderId.
      var provider = getProviderForProviderId(methods[0]);
      // At this point, you should let the user know that they already have an
      // account with a different provider, and validate they want to sign in
      // with the new provider.
      // Note: Browsers usually block popups triggered asynchronously, so in
      // real app, you should ask the user to click on a "Continue" button
      // that will trigger signInWithPopup().
      auth.signInWithPopup(provider).then(result => {
        // Note: Identity Platform doesn't control the provider's sign-in
        // flow, so it's possible for the user to sign in with an account
        // with a different email from the first one.

        // Link the Facebook credential. We have access to the pending
        // credential, so we can directly call the link method.
        result.user.linkWithCredential(pendingCred).then(usercred => {
          // Success.
          goToApp();
        });
      });
    });
  }
});

L'utilisation d'une redirection est semblable à une fenêtre pop-up, à la différence que vous devez mettre en cache l'identifiant en attente entre les redirections de pages (par exemple, en utilisant l'espace de stockage de session).

Notez que certains fournisseurs, tels que Google et Microsoft, servent à la fois de fournisseurs de messagerie et d'identité sociale. Les fournisseurs de messagerie sont considérés comme faisant autorité pour toutes les adresses associées à leur domaine de messagerie hébergé. Cela signifie qu'un utilisateur qui se connecte avec une adresse e-mail hébergée par le même fournisseur ne génère jamais cette erreur (par exemple, se connecter à Google en utilisant une adresse e-mail @gmail.com, ou à Microsoft en utilisant une adresse e-mail @live.com ou @outlook.com.)

Fusionner des comptes manuellement

Si un utilisateur tente de se connecter en utilisant le même fournisseur avec des identifiants déjà associés à un autre compte utilisateur, les méthodes intégrées du SDK client pour l'association de comptes échouent. Dans ce cas, vous devez fusionner les comptes manuellement, puis supprimer le deuxième compte. Exemple :

JavaScript

// Sign in first account.
const result1 = await auth.signInWithCredential(cred1);
const user1 = result1.user;
// Try to link a credential that belongs to an existing account
try {
  await user1.linkWithCredential(cred2);
} catch (error) {
  // cred2 already exists so an error is thrown.
  const result2 = await auth.signInWithCredential(error.credential);
  const user2 = result2.user;
  // Merge the data.
  mergeData(user1, user2);
  // Delete one of the accounts, and try again.
  await user2.delete();
  // Linking now will work.
  await user1.linkWithCredential(result2.credential);
}

Vous pouvez dissocier un fournisseur du compte d'un utilisateur. L'utilisateur ne pourra plus s'authentifier avec ce fournisseur.

Pour dissocier un fournisseur, transmettez l'ID de fournisseur à la méthode unlink() sur l'utilisateur. Vous pouvez obtenir l'ID à partir de la propriété providerData.

JavaScript

user.unlink(providerId).then(() => {
  // Auth provider unlinked from account
  // ...
}).catch((error) => {
  // An error happened
  // ...
});

Étape suivante