Authentifizieren Sie sich bei Firebase mithilfe des E-Mail-Links in JavaScript

Sie können die Firebase-Authentifizierung verwenden, um einen Benutzer anzumelden, indem Sie ihm eine E-Mail mit einem Link senden, auf den er klicken kann, um sich anzumelden. Dabei wird auch die E-Mail-Adresse des Benutzers verifiziert.

Die Anmeldung per E-Mail bietet zahlreiche Vorteile:

  • Reibungslose Anmeldung und Anmeldung.
  • Geringeres Risiko der Wiederverwendung von Passwörtern über Anwendungen hinweg, was die Sicherheit selbst gut ausgewählter Passwörter untergraben kann.
  • Die Möglichkeit, einen Benutzer zu authentifizieren und gleichzeitig zu überprüfen, ob der Benutzer der rechtmäßige Eigentümer einer E-Mail-Adresse ist.
  • Ein Benutzer benötigt nur ein zugängliches E-Mail-Konto, um sich anzumelden. Es ist kein Besitz einer Telefonnummer oder eines Social-Media-Kontos erforderlich.
  • Ein Benutzer kann sich sicher anmelden, ohne ein Kennwort angeben (oder sich merken) zu müssen, was auf einem mobilen Gerät umständlich sein kann.
  • Ein bestehender Benutzer, der sich zuvor mit einer E-Mail-Kennung (Kennwort oder Verbund) angemeldet hat, kann aktualisiert werden, um sich nur mit der E-Mail anzumelden. Beispielsweise kann sich ein Benutzer, der sein Kennwort vergessen hat, immer noch anmelden, ohne sein Kennwort zurücksetzen zu müssen.

Bevor Sie beginnen

Falls noch nicht geschehen, kopieren Sie das Initialisierungs-Snippet aus der Firebase-Konsole in Ihr Projekt, wie unter Hinzufügen von Firebase zu Ihrem JavaScript-Projekt beschrieben.

Um Benutzer per E-Mail-Link anzumelden, müssen Sie zuerst die Anmeldemethode E-Mail-Anbieter und E-Mail-Link für Ihr Firebase-Projekt aktivieren:

  1. Öffnen Sie in der Firebase-Konsole den Abschnitt Auth .
  2. Aktivieren Sie auf der Registerkarte Anmeldemethode den E-Mail-/Kennwortanbieter . Beachten Sie, dass die Anmeldung per E-Mail/Passwort aktiviert sein muss, um die Anmeldung per E-Mail-Link zu verwenden.
  3. Aktivieren Sie im selben Abschnitt die Anmeldemethode E-Mail-Link (kennwortlose Anmeldung) .
  4. Klicken Sie auf Speichern .

Präsentieren Sie dem Benutzer zum Initiieren des Authentifizierungsflusses eine Schnittstelle, die ihn auffordert, seine E-Mail-Adresse anzugeben, und rufen Sie dann sendSignInLinkToEmail auf, um anzufordern, dass Firebase den Authentifizierungslink an die E-Mail-Adresse des Benutzers sendet.

  1. Erstellen Sie das ActionCodeSettings Objekt, das Firebase Anweisungen zum Erstellen des E-Mail-Links bereitstellt. Legen Sie die folgenden Felder fest:

    • url : Der einzubettende Deep-Link und jeder zusätzliche Zustand, der weitergegeben werden soll. Die Domäne des Links muss in der Liste der autorisierten Domänen der Firebase-Konsole hinzugefügt werden, die auf der Registerkarte Anmeldemethode (Authentifizierung -> Anmeldemethode) zu finden ist.
    • android und ios : Die zu verwendenden Apps, wenn der Anmeldelink auf einem Android- oder Apple-Gerät geöffnet wird. Erfahren Sie mehr darüber, wie Sie Firebase Dynamic Links konfigurieren , um E-Mail-Aktionslinks über mobile Apps zu öffnen.
    • handleCodeInApp : Auf true setzen. Der Anmeldevorgang muss im Gegensatz zu anderen Out-of-Band-E-Mail-Aktionen (Passwortzurücksetzung und E-Mail-Bestätigungen) immer in der App abgeschlossen werden. Dies liegt daran, dass der Benutzer am Ende des Flusses voraussichtlich angemeldet ist und sein Authentifizierungsstatus in der App beibehalten wird.
    • dynamicLinkDomain : Wenn mehrere benutzerdefinierte dynamische Linkdomänen für ein Projekt definiert sind, geben Sie an, welche verwendet werden soll, wenn der Link über eine bestimmte mobile App geöffnet werden soll (z. B. example.page.link ). Andernfalls wird automatisch die erste Domäne ausgewählt.

      Web version 9

      const actionCodeSettings = {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be in the authorized domains list in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true.
        handleCodeInApp: true,
        iOS: {
          bundleId: 'com.example.ios'
        },
        android: {
          packageName: 'com.example.android',
          installApp: true,
          minimumVersion: '12'
        },
        dynamicLinkDomain: 'example.page.link'
      };

      Web version 8

      var actionCodeSettings = {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be in the authorized domains list in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true.
        handleCodeInApp: true,
        iOS: {
          bundleId: 'com.example.ios'
        },
        android: {
          packageName: 'com.example.android',
          installApp: true,
          minimumVersion: '12'
        },
        dynamicLinkDomain: 'example.page.link'
      };

    Weitere Informationen zu ActionCodeSettings finden Sie im Abschnitt Passing State in E-Mail-Aktionen .

  2. Fragen Sie den Benutzer nach seiner E-Mail-Adresse.

  3. Senden Sie den Authentifizierungslink an die E-Mail-Adresse des Benutzers und speichern Sie die E-Mail-Adresse des Benutzers, falls der Benutzer die E-Mail-Anmeldung auf demselben Gerät abschließt.

    Web version 9

    import { getAuth, sendSignInLinkToEmail } from "firebase/auth";
    
    const auth = getAuth();
    sendSignInLinkToEmail(auth, email, actionCodeSettings)
      .then(() => {
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        window.localStorage.setItem('emailForSignIn', email);
        // ...
      })
      .catch((error) => {
        const errorCode = error.code;
        const errorMessage = error.message;
        // ...
      });

    Web version 8

    firebase.auth().sendSignInLinkToEmail(email, actionCodeSettings)
      .then(() => {
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        window.localStorage.setItem('emailForSignIn', email);
        // ...
      })
      .catch((error) => {
        var errorCode = error.code;
        var errorMessage = error.message;
        // ...
      });

Sicherheitsbedenken

Um zu verhindern, dass ein Anmeldelink verwendet wird, um sich als unbeabsichtigter Benutzer oder auf einem unbeabsichtigten Gerät anzumelden, erfordert Firebase Auth die Angabe der E-Mail-Adresse des Benutzers, wenn der Anmeldevorgang abgeschlossen wird. Damit die Anmeldung erfolgreich ist, muss diese E-Mail-Adresse mit der Adresse übereinstimmen, an die der Anmeldelink ursprünglich gesendet wurde.

Sie können diesen Ablauf für Benutzer optimieren, die den Anmeldelink auf demselben Gerät öffnen, auf dem sie den Link anfordern, indem Sie ihre E-Mail-Adresse lokal speichern – beispielsweise mithilfe von localStorage oder Cookies –, wenn Sie die Anmelde-E-Mail senden. Verwenden Sie dann diese Adresse, um den Flow abzuschließen. Übergeben Sie die E-Mail-Adresse des Benutzers nicht in den Umleitungs-URL-Parametern und verwenden Sie sie erneut, da dies Sitzungsinjektionen ermöglichen kann.

Nach Abschluss der Anmeldung werden alle vorherigen unbestätigten Anmeldemechanismen des Benutzers entfernt und alle vorhandenen Sitzungen werden ungültig. Wenn beispielsweise jemand zuvor ein unbestätigtes Konto mit derselben E-Mail-Adresse und demselben Passwort erstellt hat, wird das Passwort des Benutzers entfernt, um zu verhindern, dass sich der Imitator, der die Inhaberschaft beansprucht und dieses unbestätigte Konto erstellt hat, erneut mit der unbestätigten E-Mail-Adresse und dem unbestätigten Passwort anmeldet.

Stellen Sie außerdem sicher, dass Sie in der Produktion eine HTTPS-URL verwenden, um zu vermeiden, dass Ihr Link möglicherweise von zwischengeschalteten Servern abgefangen wird.

Abschließen der Anmeldung auf einer Webseite

Das Format des E-Mail-Link-Deeplinks ist dasselbe wie das Format, das für Out-of-Band-E-Mail-Aktionen verwendet wird (E-Mail-Bestätigung, Zurücksetzen des Passworts und Widerruf der E-Mail-Änderung). Firebase Auth vereinfacht diese Prüfung, indem es die isSignInWithEmailLink API bereitstellt, um zu prüfen, ob es sich bei einem Link um einen Link zur Anmeldung mit E-Mail handelt.

Um die Anmeldung auf der Zielseite abzuschließen, rufen signInWithEmailLink mit der E-Mail-Adresse des Benutzers und dem tatsächlichen E-Mail-Link auf, der den einmaligen Code enthält.

Web version 9

import { getAuth, isSignInWithEmailLink, signInWithEmailLink } from "firebase/auth";

// Confirm the link is a sign-in with email link.
const auth = getAuth();
if (isSignInWithEmailLink(auth, window.location.href)) {
  // Additional state parameters can also be passed via URL.
  // This can be used to continue the user's intended action before triggering
  // the sign-in operation.
  // Get the email if available. This should be available if the user completes
  // the flow on the same device where they started it.
  let email = window.localStorage.getItem('emailForSignIn');
  if (!email) {
    // User opened the link on a different device. To prevent session fixation
    // attacks, ask the user to provide the associated email again. For example:
    email = window.prompt('Please provide your email for confirmation');
  }
  // The client SDK will parse the code from the link for you.
  signInWithEmailLink(auth, email, window.location.href)
    .then((result) => {
      // Clear email from storage.
      window.localStorage.removeItem('emailForSignIn');
      // You can access the new user via result.user
      // Additional user info profile not available via:
      // result.additionalUserInfo.profile == null
      // You can check if the user is new or existing:
      // result.additionalUserInfo.isNewUser
    })
    .catch((error) => {
      // Some error occurred, you can inspect the code: error.code
      // Common errors could be invalid email and invalid or expired OTPs.
    });
}

Web version 8

// Confirm the link is a sign-in with email link.
if (firebase.auth().isSignInWithEmailLink(window.location.href)) {
  // Additional state parameters can also be passed via URL.
  // This can be used to continue the user's intended action before triggering
  // the sign-in operation.
  // Get the email if available. This should be available if the user completes
  // the flow on the same device where they started it.
  var email = window.localStorage.getItem('emailForSignIn');
  if (!email) {
    // User opened the link on a different device. To prevent session fixation
    // attacks, ask the user to provide the associated email again. For example:
    email = window.prompt('Please provide your email for confirmation');
  }
  // The client SDK will parse the code from the link for you.
  firebase.auth().signInWithEmailLink(email, window.location.href)
    .then((result) => {
      // Clear email from storage.
      window.localStorage.removeItem('emailForSignIn');
      // You can access the new user via result.user
      // Additional user info profile not available via:
      // result.additionalUserInfo.profile == null
      // You can check if the user is new or existing:
      // result.additionalUserInfo.isNewUser
    })
    .catch((error) => {
      // Some error occurred, you can inspect the code: error.code
      // Common errors could be invalid email and invalid or expired OTPs.
    });
}

Abschließen der Anmeldung in einer mobilen App

Die Firebase-Authentifizierung verwendet dynamische Firebase-Links, um den E-Mail-Link an ein mobiles Gerät zu senden. Für den Anmeldeabschluss über eine mobile Anwendung muss die Anwendung so konfiguriert werden, dass sie den eingehenden Anwendungslink erkennt, den zugrunde liegenden Deep-Link parst und dann die Anmeldung wie über den Webflow abschließt.

Weitere Informationen zum Umgang mit der Anmeldung mit einem E-Mail-Link in einer Android-Anwendung finden Sie im Android-Handbuch .

Weitere Informationen zum Umgang mit der Anmeldung mit einem E-Mail-Link in einer Apple-Anwendung finden Sie im Apple-Plattformhandbuch .

Sie können diese Authentifizierungsmethode auch mit einem vorhandenen Benutzer verknüpfen. Beispielsweise kann ein Benutzer, der zuvor bei einem anderen Anbieter authentifiziert wurde, z. B. eine Telefonnummer, diese Anmeldemethode zu seinem bestehenden Konto hinzufügen.

Der Unterschied wäre in der zweiten Hälfte der Operation:

Web version 9

import { getAuth, linkWithCredential, EmailAuthProvider } from "firebase/auth";

// Construct the email link credential from the current URL.
const credential = EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Link the credential to the current user.
const auth = getAuth();
linkWithCredential(auth.currentUser, credential)
  .then((usercred) => {
    // The provider is now successfully linked.
    // The phone user can now sign in with their phone number or email.
  })
  .catch((error) => {
    // Some error occurred.
  });

Web version 8

// Construct the email link credential from the current URL.
var credential = firebase.auth.EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Link the credential to the current user.
firebase.auth().currentUser.linkWithCredential(credential)
  .then((usercred) => {
    // The provider is now successfully linked.
    // The phone user can now sign in with their phone number or email.
  })
  .catch((error) => {
    // Some error occurred.
  });

Dies kann auch verwendet werden, um einen E-Mail-Link-Benutzer erneut zu authentifizieren, bevor eine vertrauliche Operation ausgeführt wird.

Web version 9

import { getAuth, reauthenticateWithCredential, EmailAuthProvider } from "firebase/auth";

// Construct the email link credential from the current URL.
const credential = EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Re-authenticate the user with this credential.
const auth = getAuth();
reauthenticateWithCredential(auth.currentUser, credential)
  .then((usercred) => {
    // The user is now successfully re-authenticated and can execute sensitive
    // operations.
  })
  .catch((error) => {
    // Some error occurred.
  });

Web version 8

// Construct the email link credential from the current URL.
var credential = firebase.auth.EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Re-authenticate the user with this credential.
firebase.auth().currentUser.reauthenticateWithCredential(credential)
  .then((usercred) => {
    // The user is now successfully re-authenticated and can execute sensitive
    // operations.
  })
  .catch((error) => {
    // Some error occurred.
  });

Da der Flow jedoch auf einem anderen Gerät landen könnte, auf dem der ursprüngliche Benutzer nicht angemeldet war, wird dieser Flow möglicherweise nicht abgeschlossen. In diesem Fall kann dem Benutzer ein Fehler angezeigt werden, um ihn zu zwingen, den Link auf demselben Gerät zu öffnen. Im Link kann ein Status übergeben werden, um Informationen über die Art der Operation und die Benutzer-UID bereitzustellen.

Falls Sie sowohl die kennwort- als auch die linkbasierte Anmeldung mit E-Mail unterstützen, verwenden fetchSignInMethodsForEmail , um die Anmeldemethode für einen Kennwort-/Link-Benutzer zu unterscheiden. Dies ist nützlich für Identifier-First-Flows, bei denen der Benutzer zuerst aufgefordert wird, seine E-Mail-Adresse anzugeben, und dann die Anmeldemethode angezeigt wird:

Web version 9

import { getAuth, fetchSignInMethodsForEmail, EmailAuthProvider} from "firebase/auth";

// After asking the user for their email.
const email = window.prompt('Please provide your email');

const auth = getAuth();
fetchSignInMethodsForEmail(auth, email)
  .then((signInMethods) => {
    // This returns the same array as fetchProvidersForEmail but for email
    // provider identified by 'password' string, signInMethods would contain 2
    // different strings:
    // 'emailLink' if the user previously signed in with an email/link
    // 'password' if the user has a password.
    // A user could have both.
    if (signInMethods.indexOf(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/password.
    }
    if (signInMethods.indexOf(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/link.
    }
  })
  .catch((error) => {
    // Some error occurred, you can inspect the code: error.code
  });

Web version 8

// After asking the user for their email.
var email = window.prompt('Please provide your email');
firebase.auth().fetchSignInMethodsForEmail(email)
  .then((signInMethods) => {
    // This returns the same array as fetchProvidersForEmail but for email
    // provider identified by 'password' string, signInMethods would contain 2
    // different strings:
    // 'emailLink' if the user previously signed in with an email/link
    // 'password' if the user has a password.
    // A user could have both.
    if (signInMethods.indexOf(
            firebase.auth.EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/password.
    }
    if (signInMethods.indexOf(
            firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/link.
    }
  })
  .catch((error) => {
    // Some error occurred, you can inspect the code: error.code
  });

Wie oben beschrieben gelten E-Mail/Passwort und E-Mail/Link als derselbe firebase.auth.EmailAuthProvider (dieselbe PROVIDER_ID ) mit unterschiedlichen Anmeldemethoden.

Nächste Schritte

Nachdem sich ein Benutzer zum ersten Mal angemeldet hat, wird ein neues Benutzerkonto erstellt und mit den Anmeldeinformationen verknüpft – d. h. dem Benutzernamen und Kennwort, der Telefonnummer oder den Authentifizierungsanbieterinformationen –, mit denen sich der Benutzer angemeldet hat. Dieses neue Konto wird als Teil Ihres Firebase-Projekts gespeichert und kann verwendet werden, um einen Benutzer in jeder App in Ihrem Projekt zu identifizieren, unabhängig davon, wie sich der Benutzer anmeldet.

  • In Ihren Apps besteht die empfohlene Möglichkeit, den Authentifizierungsstatus Ihres Benutzers zu erfahren, darin, einen Beobachter für das Auth festzulegen. Sie können dann die grundlegenden Profilinformationen des Benutzers aus dem User abrufen. Siehe Benutzer verwalten .

  • In Ihren Sicherheitsregeln für die Firebase-Echtzeitdatenbank und den Cloud-Speicher können Sie die eindeutige Benutzer-ID des angemeldeten Benutzers aus der Variablen auth und damit steuern, auf welche Daten ein Benutzer zugreifen kann.

Sie können Benutzern erlauben, sich mit mehreren Authentifizierungsanbietern bei Ihrer App anzumelden, indem Sie die Anmeldeinformationen des Authentifizierungsanbieters mit einem vorhandenen Benutzerkonto verknüpfen.

Um einen Benutzer abzumelden, rufen signOut :

Web version 9

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

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

Web version 8

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});