Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Collegamento di più provider a un account

Questo documento mostra come collegare più provider a un singolo account Identity Platform.

Identity Platform utilizza un ID univoco per identificare gli utenti. Questo consente agli utenti di accedere allo stesso account con provider diversi. Ad esempio, un utente che inizialmente si è registrato con un numero di telefono può successivamente collegare il proprio Account Google, quindi utilizzare uno dei due metodi per accedere.

Prima di iniziare

Aggiungi il supporto per due o più provider di identità alla tua app.

Attivazione o disattivazione del collegamento degli account

L'impostazione di collegamento dell'account determina il modo in cui Identity Platform gestisce gli utenti che tentano di accedere con lo stesso indirizzo email utilizzando provider diversi.

  • Collegare gli account che utilizzano la stessa email: Identity Platform genera un errore se un utente tenta di accedere con un'email già in uso. La tua app può rilevare questo errore e collegare il nuovo provider al suo account esistente.

  • Crea più account per ogni provider di identità: verrà creato un nuovo account utente Identity Platform ogni volta che un utente accede con un provider diverso.

Per scegliere un'impostazione:

  1. Vai alla pagina Impostazioni di Identity Platform nella console Google Cloud.

    Vai alla pagina Impostazioni

  2. Seleziona un'impostazione in Collegamento account utente.

  3. Fai clic su Salva.

Collegamento delle credenziali del provider federato

Per collegare le credenziali da un provider federato:

  1. Consentire l'accesso all'utente con qualsiasi metodo o provider di autenticazione.

  2. Recupera l'oggetto provider corrispondente al provider che vuoi collegare all'account dell'utente. Ad esempio:

    Versione 9 del Web

    import { GoogleAuthProvider, FacebookAuthProvider, TwitterAuthProvider, GithubAuthProvider } from "firebase/auth";
    
    const googleProvider = new GoogleAuthProvider();
    const facebookProvider = new FacebookAuthProvider();
    const twitterProvider = new TwitterAuthProvider();
    const githubProvider = new GithubAuthProvider();

    Versione 8 web

    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. Chiedi all'utente di accedere con il provider che vuoi collegare. Puoi aprire una finestra popup o reindirizzare la pagina corrente. Il reindirizzamento è più semplice per gli utenti che utilizzano dispositivi mobili.

    Per mostrare un popup, chiama linkWithPopup().

    Versione 9 del Web

    import { getAuth, linkWithPopup, GoogleAuthProvider } from "firebase/auth";
    const provider = new GoogleAuthProvider();
    
    const auth = getAuth();
    linkWithPopup(auth.currentUser, provider).then((result) => {
      // Accounts successfully linked.
      const credential = GoogleAuthProvider.credentialFromResult(result);
      const user = result.user;
      // ...
    }).catch((error) => {
      // Handle Errors here.
      // ...
    });

    Versione 8 web

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

    Per reindirizzare la pagina, per prima cosa chiama linkWithRedirect():

    Segui le best practice quando utilizzi signInWithRedirect, linkWithRedirect o reauthenticateWithRedirect.

    Versione 9 del Web

    import { getAuth, linkWithRedirect, GoogleAuthProvider } from "firebase/auth";
    const provider = new GoogleAuthProvider();
    
    const auth = getAuth();
    linkWithRedirect(auth.currentUser, provider)
      .then(/* ... */)
      .catch(/* ... */);

    Versione 8 web

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

    Una volta effettuato l'accesso, l'utente verrà reindirizzato alla tua app. In seguito, potrai recuperare il risultato dell'accesso chiamando getRedirectResult():

    Versione 9 del Web

    import { getRedirectResult } from "firebase/auth";
    getRedirectResult(auth).then((result) => {
      const credential = GoogleAuthProvider.credentialFromResult(result);
      if (credential) {
        // Accounts successfully linked.
        const user = result.user;
        // ...
      }
    }).catch((error) => {
      // Handle Errors here.
      // ...
    });

    Versione 8 web

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

L'account dell'utente con il provider federato è ora collegato al suo account Identity Platform, che potrà utilizzare il provider per accedere.

Collegamento di credenziali email e password

Per aggiungere un indirizzo email e una password a un account utente esistente:

  1. Consentire l'accesso all'utente con qualsiasi provider o metodo di identità.

  2. Chiedi all'utente un indirizzo email e una password.

  3. Crea un oggetto AuthCredential con l'indirizzo email e la password:

    Versione 9 del Web

    import { EmailAuthProvider } from "firebase/auth";
    
    const credential = EmailAuthProvider.credential(email, password);

    Versione 8 web

    var credential = firebase.auth.EmailAuthProvider.credential(email, password);
  4. Passa l'oggetto AuthCredential al metodo linkWithCredential() dell'utente che ha eseguito l'accesso:

    Versione 9 del Web

    import { getAuth, linkWithCredential } from "firebase/auth";
    
    const auth = getAuth();
    linkWithCredential(auth.currentUser, credential)
      .then((usercred) => {
        const user = usercred.user;
        console.log("Account linking success", user);
      }).catch((error) => {
        console.log("Account linking error", error);
      });

    Versione 8 web

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

Le credenziali email e password sono ora collegate all'account Identity Platform dell'utente, il quale potrà utilizzarle per accedere.

Tieni presente che le credenziali di un provider federato possono essere collegate a un account email/password con un indirizzo email diverso. In questo caso, l'indirizzo email corrispondente al provider federato può essere utilizzato per creare un account email/password separato.

Gestire l'errore account-exists-with-Different-credential

Se hai abilitato l'impostazione Collega account che utilizzano la stessa email in Google Cloud Console, quando un utente tenta di accedere a un provider (ad esempio SAML) con un indirizzo email già esistente per un altro provider (ad esempio Google), viene generato l'errore auth/account-exists-with-different-credential (insieme a un oggetto AuthCredential).

Per gestire questo errore, chiedi all'utente di accedere con il provider esistente. Quindi chiama linkWithCredential(), linkWithPopup() o linkWithRedirect() per associare il nuovo fornitore al suo account utilizzando AuthCredential.

L'esempio seguente mostra come gestire questo errore quando un utente tenta di accedere utilizzando 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'uso di un reindirizzamento è simile a un popup, con l'eccezione che devi memorizzare nella cache le credenziali in sospeso tra i reindirizzamenti delle pagine (ad esempio, utilizzando lo spazio di archiviazione della sessione).

Tieni presente che alcuni provider, come Google e Microsoft, fungono sia da provider di email sia da social network. I provider email sono considerati autorevoli per tutti gli indirizzi correlati al dominio email ospitato. Questo significa che un utente che esegue l'accesso con un indirizzo email ospitato dallo stesso provider non genererà mai questo errore (ad esempio, se accede con Google utilizzando un'email @gmail.com o Microsoft utilizzando un'email @live.com o @outlook.com).

Unione manuale degli account

Se un utente tenta di accedere con credenziali già collegate a un altro account utente utilizzando lo stesso provider, i metodi integrati per il collegamento dell'account dell'SDK client non andranno a buon fine. In questo caso, dovrai unire gli account manualmente e poi eliminare il secondo account. Ad esempio:

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

Puoi scollegare un fornitore dall'account di un utente. L'utente non potrà più eseguire l'autenticazione con quel provider.

Per scollegare un provider, trasmetti il relativo ID al metodo unlink(). Puoi ottenere gli ID provider dei provider di autenticazione collegati a un utente dalla proprietà providerData.

Versione 9 del Web

import { getAuth, unlink } from "firebase/auth";

const auth = getAuth();
unlink(auth.currentUser, providerId).then(() => {
  // Auth provider unlinked from account
  // ...
}).catch((error) => {
  // An error happened
  // ...
});

Versione 8 web

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

Passaggi successivi