Mehrere Anbieter mit einem Konto verknüpfen

In diesem Dokument wird gezeigt, wie Sie mehrere Anbieter mit einem einzigen Identity Platform-Konto verknüpfen.

Identity Platform verwendet eine eindeutige ID, um Nutzer zu identifizieren. Auf diese Weise können sich Nutzer mit unterschiedlichen Anbietern im selben Konto anmelden. Beispielsweise kann ein Nutzer, der sich ursprünglich mit einer Telefonnummer registriert hat, später sein Google-Konto verknüpfen und sich dann auf eine der beiden Arten anmelden.

Hinweis

Fügen Sie Ihrer Anwendung zwei oder mehr Identitätsanbieter hinzu.

Kontoverknüpfung aktivieren oder deaktivieren

Mit der Kontoverknüpfungseinstellung wird festgelegt, wie Identity Platform die Nutzer behandelt, die versuchen, sich mit derselben E-Mail-Adresse über verschiedene Anbieter anzumelden.

  • Konten mit derselben E-Mail-Adresse verknüpfen: Identity Platform gibt einen Fehler aus, wenn ein Nutzer versucht, sich mit einer E-Mail-Adresse anzumelden, die bereits verwendet wird. Ihre Anwendung kann diesen Fehler erkennen und den neuen Anbieter mit seinem bestehenden Konto verknüpfen.

  • Mehrere Konten für jeden Identitätsanbieter erstellen: Jedes Mal, wenn sich ein Nutzer bei einem anderen Anbieter anmeldet, wird ein neues Identity Platform-Nutzerkonto erstellt.

So wählen Sie eine Einstellung aus:

  1. Rufen Sie in der Google Cloud Console die Seite Identity Platform-Einstellungen auf.

    Zur Seite "Einstellungen"

  2. Wählen Sie unter Kontoverknüpfung eine Einstellung aus.

  3. Klicken Sie auf Speichern.

Anmeldedaten eines föderierten Anbieters verknüpfen

So verknüpfen Sie die Anmeldedaten eines föderierten Anbieters:

  1. Melden Sie sich mit einem beliebigen Authentifizierungsanbieter oder einer Methode an.

  2. Rufen Sie das Anbieterobjekt ab, das dem Anbieter entspricht, den Sie mit dem Nutzerkonto verknüpfen möchten. Beispiel:

    Webversion 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. Bitten Sie den Nutzer, sich mit dem Anbieter anzumelden, den Sie verknüpfen möchten. Sie können entweder ein Pop-up-Fenster öffnen oder die aktuelle Seite weiterleiten. Für Nutzer von Mobilgeräten ist die Weiterleitung einfacher.

    Rufen Sie linkWithPopup() auf, um ein Pop-up-Fenster einzublenden:

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

    Rufen Sie zum Weiterleiten der Seite zuerst linkWithRedirect() auf:

    Folgen Sie den Best Practices für die Verwendung von signInWithRedirect, linkWithRedirect oder reauthenticateWithRedirect.

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

    Nachdem der Nutzer sich angemeldet hat, wird er zu Ihrer Anwendung zurückgeleitet. Anschließend können Sie das Anmeldeergebnis durch Aufrufen von getRedirectResult() abrufen:

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

Das Nutzerkonto des föderierten Anbieters ist jetzt mit seinem Identity Platform-Konto verknüpft und kann sich über den Anbieter anmelden.

E-Mail-Adresse und Passwort als Anmeldedaten verknüpfen

So fügen Sie einem vorhandenen Nutzerkonto eine E-Mail-Adresse und ein Passwort hinzu:

  1. Melden Sie sich mit einem beliebigen Identitätsanbieter oder einer beliebigen Methode an.

  2. Fordern Sie den Nutzer zur Eingabe einer E-Mail-Adresse und eines Passworts auf.

  3. Erstellen Sie ein AuthCredential-Objekt mit der E-Mail-Adresse und dem Passwort:

    Webversion 9

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

    Webversion 8

    var credential = firebase.auth.EmailAuthProvider.credential(email, password);
  4. Übergeben Sie das AuthCredential-Objekt an die Methode linkWithCredential() des angemeldeten Nutzers:

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

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

Die E-Mail-Adresse und das Passwort sind jetzt mit dem Identity Platform-Konto des Nutzers verknüpft und können sich damit anmelden.

Beachten Sie, dass Anmeldedaten eines föderierten Anbieters mit einem E-Mail-/Passwort-Konto mit einer anderen E-Mail-Adresse verknüpft werden können. In diesem Fall kann die E-Mail-Adresse, die dem föderierten Anbieter entspricht, verwendet werden, um ein separates E-Mail-/Passwortkonto zu erstellen.

Fehler "account-exists-with-different-credential" bearbeiten

Wenn Sie in Ihrem Konto die Einstellung Konten verknüpfen, die dieselbe E-Mail-Adresse verwenden aktiviert haben, Google Cloud Console, wenn ein Nutzer versucht, sich bei einem Anbieter anzumelden (z. B. SAML) mit einer E-Mail-Adresse, die bereits für einen anderen Anbieter existiert (z. B. Google) erhalten, wird der Fehler auth/account-exists-with-different-credential (zusammen mit einem AuthCredential-Objekt).

Bitten Sie den Nutzer, sich beim vorhandenen Anbieter anzumelden, um diesen Fehler zu beheben. Rufen Sie dann linkWithCredential(), linkWithPopup() oder linkWithRedirect() auf, um den neuen Anbieter mit seinem Konto über die AuthCredential zu verknüpfen.

Das folgende Beispiel zeigt, wie dieser Fehler behoben wird, wenn ein Nutzer versucht, sich mit Facebook anzumelden:

Web version 9

  import { signInWithPopup, signInWithEmailAndPassword, linkWithCredential } from "firebase/auth";

  // User tries to sign in with Facebook.
  signInWithPopup(auth, facebookProvider).catch((error) => {
  // User's email already exists.
  if (error.code === 'auth/account-exists-with-different-credential') {
    // The pending Facebook credential.
    const pendingCred = error.credential;
    // The provider account's email address.
    const email = error.customData.email;

    // Present the user with a list of providers they might have
    // used to create the original account.
    // Then, ask the user to sign in with the existing provider.
    const method = promptUserForSignInMethod();

    if (method === 'password') {
      // TODO: Ask the user for their password.
      // In real scenario, you should handle this asynchronously.
      const password = promptUserForPassword();
      signInWithEmailAndPassword(auth, email, password).then((result) => {
        return linkWithCredential(result.user, 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.
    const provider = getProviderForProviderId(method);
    // 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().
    signInWithPopup(auth, 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.
      linkWithCredential(result.user, pendingCred).then((userCred) => {
        // Success.
        goToApp();
      });
    });
  }
});

Webversion 8

  // User tries to sign in with Facebook.
      auth.signInWithPopup(facebookProvider).catch((error) => {
  // User's email already exists.
  if (error.code === 'auth/account-exists-with-different-credential') {
    // The pending Facebook credential.
    const pendingCred = error.credential;
    // The provider account's email address.
    const email = error.email;

    // Present the user with a list of providers they might have
    // used to create the original account.
    // Then, ask the user to sign in with the existing provider.
    const method = promptUserForSignInMethod();

    if (method === 'password') {
      // TODO: Ask the user for their password.
      // In real scenario, you should handle this asynchronously.
      const 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.
    const provider = getProviderForProviderId(method);
    // 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();
      });
    });
  }
});

Weiterleitungen sind ähnlich wie Pop-ups, es sei denn, Sie speichern die ausstehenden Anmeldedaten zwischen den Seitenweiterleitungen (z. B. mit Sitzungsspeicher).

Beachten Sie, dass einige Anbieter, z. B. Google und Microsoft, sowohl als E-Mail- als auch als Anbieter von sozialen Identitäten dienen. E-Mail-Anbieter gelten als vertrauenswürdig für alle Adressen, die mit ihrer gehosteten E-Mail-Domain zusammenhängen. Das bedeutet, dass sich ein Nutzer, der sich mit einer E-Mail-Adresse anmeldet, die vom selben Anbieter gehostet wird, nie diesen Fehler auslöst. Er kann sich z. B. mit einer @gmail.com-E-Mail bei Google anmelden oder bei Microsoft mit einer @live.com-oder @outlook.com-E-Mail).

Konten manuell zusammenführen

Wenn ein Nutzer versucht, sich mit Anmeldedaten eines anderen Nutzers, der bereits mit demselben Anbieter verknüpft ist, anzumelden, schlagen die integrierten Methoden des Client-SDK zur Kontoverknüpfung fehl. In diesem Fall müssen Sie die Konten manuell zusammenführen und dann das zweite Konto löschen. Beispiel:

Webversion 9

// Sign in first account.
const result1 = await signInWithCredential(auth, cred1);
const user1 = result1.user;
// Try to link a credential that belongs to an existing account
try {
  await linkWithCredential(user1, cred2);
} catch (error) {
  // cred2 already exists so an error is thrown.
  const result2 = await signInWithCredential(auth, 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 linkWithCredential(user1, result2.credential);
}

Web version 8

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

Sie können die Verknüpfung zwischen einem Anbieter und dem Konto eines Nutzers aufheben. Der Nutzer kann sich nicht mehr bei diesem Anbieter authentifizieren.

Wenn Sie die Verknüpfung eines Anbieters aufheben möchten, übergeben Sie die Anbieter-ID an die Methode unlink(). Du kannst die Anbieter-IDs der Authentifizierungsanbieter abrufen, die mit einem Nutzer über die Property providerData verknüpft sind.

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

Nächste Schritte