Połącz wielu dostawców uwierzytelniania z kontem za pomocą JavaScript

Możesz zezwolić użytkownikom na logowanie się do Twojej aplikacji przy użyciu wielu dostawców uwierzytelniania, łącząc poświadczenia dostawcy uwierzytelniania z istniejącym kontem użytkownika. Użytkowników można zidentyfikować za pomocą tego samego identyfikatora użytkownika Firebase niezależnie od dostawcy uwierzytelniania, którego użyli do zalogowania. Na przykład użytkownik, który zalogował się za pomocą hasła, może połączyć konto Google i zalogować się za pomocą dowolnej metody w przyszłości. Lub anonimowy użytkownik może połączyć konto na Facebooku, a następnie później zalogować się na Facebooku, aby nadal korzystać z Twojej aplikacji.

Zanim zaczniesz

Dodaj do swojej aplikacji obsługę co najmniej dwóch dostawców uwierzytelniania (być może łącznie z uwierzytelnianiem anonimowym).

Aby połączyć poświadczenia od dostawcy uwierzytelniania, takiego jak Google lub Facebook, z istniejącym kontem użytkownika:

  1. Zaloguj użytkownika przy użyciu dowolnego dostawcy lub metody uwierzytelniania.
  2. Pobierz obiekt AuthProvider odpowiadający dostawcy, którego chcesz połączyć z kontem użytkownika. Przykłady:

    Web version 9

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

    Web version 8

    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. Poproś użytkownika o zalogowanie się u dostawcy, którego chcesz połączyć. Możesz poprosić użytkowników o zalogowanie się, otwierając wyskakujące okienko lub przekierowując na stronę logowania dostawcy. Metoda przekierowania jest preferowana na urządzeniach mobilnych.
    • Aby zalogować się za pomocą wyskakującego okienka, wywołaj linkWithPopup :

      Web version 9

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

      Web version 8

      auth.currentUser.linkWithPopup(provider).then((result) => {
        // Accounts successfully linked.
        var credential = result.credential;
        var user = result.user;
        // ...
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });
    • Aby zalogować się przez przekierowanie do strony logowania dostawcy, wywołaj linkWithRedirect : postępuj zgodnie z najlepszymi praktykami podczas korzystania z `linkWithRedirect`.

      Web version 9

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

      Web version 8

      auth.currentUser.linkWithRedirect(provider)
        .then(/* ... */)
        .catch(/* ... */);
      Po zalogowaniu się użytkownik jest przekierowywany z powrotem na Twoją stronę. Następnie możesz pobrać wynik logowania, wywołując funkcję getRedirectResult podczas ładowania strony:

      Web version 9

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

      Web version 8

      auth.getRedirectResult().then((result) => {
        if (result.credential) {
          // Accounts successfully linked.
          var credential = result.credential;
          var user = result.user;
          // ...
        }
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });
    Jeśli użytkownik pomyślnie się zaloguje, konto użytkownika u dostawcy zostanie połączone z kontem użytkownika w Twoim projekcie Firebase.

    Łączenie kont nie powiedzie się, jeśli poświadczenia są już połączone z innym kontem użytkownika. W tej sytuacji musisz zająć się łączeniem kont i powiązanych danych odpowiednio do swojej aplikacji:

    Web version 9

    import { getAuth, signInWithCredential, linkWithCredential, OAuthProvider } from "firebase/auth";
    
    // The implementation of how you store your user data depends on your application
    const repo = new MyUserDataRepo();
    
    // Get reference to the currently signed-in user
    const auth = getAuth();
    const prevUser = auth.currentUser;
    
    // Get the data which you will want to merge. This should be done now
    // while the app is still signed in as this user.
    const prevUserData = repo.get(prevUser);
    
    // Delete the user's data now, we will restore it if the merge fails
    repo.delete(prevUser);
    
    // Sign in user with the account you want to link to
    signInWithCredential(auth, newCredential).then((result) => {
      console.log("Sign In Success", result);
      const currentUser = result.user;
      const currentUserData = repo.get(currentUser);
    
      // Merge prevUser and currentUser data stored in Firebase.
      // Note: How you handle this is specific to your application
      const mergedData = repo.merge(prevUserData, currentUserData);
    
      const credential = OAuthProvider.credentialFromResult(result);
      return linkWithCredential(prevUser, credential)
        .then((linkResult) => {
          // Sign in with the newly linked credential
          const linkCredential = OAuthProvider.credentialFromResult(linkResult);
          return signInWithCredential(auth, linkCredential);
        })
        .then((signInResult) => {
          // Save the merged data to the new user
          repo.set(signInResult.user, mergedData);
        });
    }).catch((error) => {
      // If there are errors we want to undo the data merge/deletion
      console.log("Sign In Error", error);
      repo.set(prevUser, prevUserData);
    });

    Web version 8

    // The implementation of how you store your user data depends on your application
    var repo = new MyUserDataRepo();
    
    // Get reference to the currently signed-in user
    var prevUser = auth.currentUser;
    
    // Get the data which you will want to merge. This should be done now
    // while the app is still signed in as this user.
    var prevUserData = repo.get(prevUser);
    
    // Delete the user's data now, we will restore it if the merge fails
    repo.delete(prevUser);
    
    // Sign in user with the account you want to link to
    auth.signInWithCredential(newCredential).then((result) => {
      console.log("Sign In Success", result);
      var currentUser = result.user;
      var currentUserData = repo.get(currentUser);
    
      // Merge prevUser and currentUser data stored in Firebase.
      // Note: How you handle this is specific to your application
      var mergedData = repo.merge(prevUserData, currentUserData);
    
      return prevUser.linkWithCredential(result.credential)
        .then((linkResult) => {
          // Sign in with the newly linked credential
          return auth.signInWithCredential(linkResult.credential);
        })
        .then((signInResult) => {
          // Save the merged data to the new user
          repo.set(signInResult.user, mergedData);
        });
    }).catch((error) => {
      // If there are errors we want to undo the data merge/deletion
      console.log("Sign In Error", error);
      repo.set(prevUser, prevUserData);
    });

Aby dodać poświadczenia adresu e-mail i hasła do istniejącego konta użytkownika:

  1. Zaloguj użytkownika przy użyciu dowolnego dostawcy lub metody uwierzytelniania.
  2. Zapytaj użytkownika o adres e-mail i nowe hasło.
  3. Utwórz obiekt AuthCredential z adresem e-mail i hasłem:

    Web version 9

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

    Web version 8

    var credential = firebase.auth.EmailAuthProvider.credential(email, password);
  4. Przekaż obiekt AuthCredential do metody linkWithCredential zalogowanego użytkownika:

    Web version 9

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

    Web version 8

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

    Wywołanie linkWithCredential zakończy się niepowodzeniem, jeśli poświadczenia są już połączone z innym kontem użytkownika. W takiej sytuacji musisz zająć się łączeniem kont i powiązanych danych odpowiednio do swojej aplikacji (patrz przykład powyżej).

Możesz odłączyć dostawcę uwierzytelniania od konta, aby użytkownik nie mógł już logować się u tego dostawcy.

Aby odłączyć dostawcę uwierzytelniania od konta użytkownika, przekaż identyfikator dostawcy do metody unlink . Możesz uzyskać identyfikatory dostawców dostawców uwierzytelniania połączonych z użytkownikiem z właściwości providerData .

Web version 9

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

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

Web version 8

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