Über einen E-Mail-Link in JavaScript mit Firebase authentifizieren

Mit Firebase Authentication können Sie einen Nutzer anmelden, 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 Nutzers bestätigt.

Die Anmeldung per E-Mail bietet zahlreiche Vorteile:

  • Einfache Registrierung und Anmeldung.
  • Geringeres Risiko der Wiederverwendung von Passwörtern in verschiedenen Anwendungen, was die Sicherheit selbst gut ausgewählter Passwörter untergraben kann.
  • Die Möglichkeit, einen Nutzer zu authentifizieren und gleichzeitig zu bestätigen, dass er der rechtmäßige Inhaber einer E-Mail-Adresse ist.
  • Ein Nutzer benötigt nur ein zugängliches E‑Mail-Konto, um sich anzumelden. Er muss keine Telefonnummer oder kein Social-Media-Konto besitzen.
  • Nutzer können sich sicher anmelden, ohne ein Passwort eingeben oder sich merken zu müssen, was auf einem Mobilgerät umständlich sein kann.
  • Ein vorhandener Nutzer, der sich zuvor mit einer E‑Mail-Kennung (Passwort oder Verbund) angemeldet hat, kann auf die Anmeldung nur mit der E‑Mail-Adresse umgestellt werden. Ein Nutzer, der sein Passwort vergessen hat, kann sich beispielsweise weiterhin anmelden, ohne sein Passwort zurücksetzen zu müssen.

Hinweis

Falls noch nicht geschehen, kopieren Sie das Initialisierungssnippet aus der Firebase Console in Ihr Projekt, wie unter Firebase zu Ihrem JavaScript-Projekt hinzufügen beschrieben.

Wenn Sie Nutzer über einen E-Mail-Link anmelden möchten, müssen Sie zuerst den E-Mail-Anbieter und die Anmeldemethode „E-Mail-Link“ für Ihr Firebase-Projekt aktivieren:

  1. Wechseln Sie in der Firebase-Konsole zu Sicherheit > Authentifizierung.

  2. Aktivieren Sie auf dem Tab Sign-in method (Anmeldemethode) die Anmeldemethode E-Mail/Passwort. Die Anmeldung mit E‑Mail-Adresse und Passwort muss aktiviert sein, damit die Anmeldung mit E‑Mail-Link verwendet werden kann.

  3. Aktivieren Sie im selben Abschnitt den Anmeldeanbieter E-Mail-Link (Anmeldung ohne Passwort).

  4. Klicken Sie auf Speichern.

Zum Initiieren des Authentifizierungsablaufs wird eine Schnittstelle angezeigt, in der der Nutzer aufgefordert wird, seine E‑Mail-Adresse anzugeben, und dann sendSignInLinkToEmail aufgerufen, um Firebase aufzufordern, den Authentifizierungslink an die E‑Mail-Adresse des Nutzers zu senden.

  1. Erstellen Sie das ActionCodeSettings-Objekt, das Firebase Anweisungen zum Erstellen des E-Mail-Links gibt. Legen Sie die Werte für die folgenden Felder fest:

    • url: Der einzubettende Deeplink und alle zusätzlichen Statusinformationen, die übergeben werden sollen. Falls noch nicht geschehen, fügen Sie Ihre Domain der Liste der autorisierten Domains hinzu:

      1. Rufen Sie in der Firebase-Konsole den Tab Einstellungen unter Sicherheit > Authentifizierung auf.

      2. Klicken Sie im Abschnitt Autorisierte Domains auf Domain hinzufügen und fügen Sie Ihre Domain hinzu.

    • android und ios: Damit kann Firebase Authentication ermitteln, ob ein reiner Weblink oder ein mobiler Link erstellt werden soll, der auf einem Android- oder Apple-Gerät geöffnet wird.
    • handleCodeInApp: Auf „true“ gesetzt. Der Anmeldevorgang muss immer in der App abgeschlossen werden, im Gegensatz zu anderen Out-of-Band-E-Mail-Aktionen (Passwort zurücksetzen und E-Mail-Bestätigungen). Das liegt daran, dass der Nutzer am Ende des Vorgangs angemeldet sein und sein Authentifizierungsstatus in der App gespeichert werden soll.
    • linkDomain: Wenn benutzerdefinierte Hosting-Linkdomains für ein Projekt definiert sind, geben Sie an, welche verwendet werden soll, wenn der Link von einer bestimmten mobilen App geöffnet werden soll. Andernfalls wird automatisch die Standarddomain ausgewählt (z. B. PROJECT_ID.firebaseapp.com).
    • dynamicLinkDomain: Veraltet. Geben Sie diesen Parameter nicht an.

      Web

      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'
        },
        // The domain must be configured in Firebase Hosting and owned by the project.
        linkDomain: 'custom-domain.com'
      };

      Web

      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 Status in E-Mail-Aktionen übergeben.

  2. Frage den Nutzer nach seiner E‑Mail-Adresse.

  3. Senden Sie den Authentifizierungslink an die E-Mail-Adresse des Nutzers und speichern Sie die E-Mail-Adresse des Nutzers für den Fall, dass der Nutzer die E-Mail-Anmeldung auf demselben Gerät abschließt.

    Web

    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

    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

Damit ein Anmeldelink nicht verwendet werden kann, um sich als ein nicht vorgesehener Nutzer oder auf einem nicht vorgesehenen Gerät anzumelden, muss bei Firebase Auth die E‑Mail-Adresse des Nutzers angegeben werden, 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 Nutzer optimieren, die den Anmeldelink auf demselben Gerät öffnen, auf dem sie ihn angefordert haben. Speichern Sie dazu die E-Mail-Adresse lokal, z. B. mit localStorage oder Cookies, wenn Sie die Anmelde-E-Mail senden. Verwenden Sie diese Adresse dann, um den Ablauf abzuschließen. Geben Sie die E-Mail-Adresse des Nutzers nicht in den Parametern der Weiterleitungs-URL an und verwenden Sie sie nicht wieder, da dies Session-Injections ermöglichen kann.

Nach der Anmeldung werden alle zuvor nicht bestätigten Anmeldemechanismen des Nutzers entfernt und alle bestehenden Sitzungen werden ungültig. Wenn beispielsweise jemand zuvor ein nicht bestätigtes Konto mit derselben E-Mail-Adresse und demselben Passwort erstellt hat, wird das Passwort des Nutzers entfernt, um zu verhindern, dass sich der Betrüger, der das Eigentum beansprucht und dieses nicht bestätigte Konto erstellt hat, noch einmal mit der nicht bestätigten E-Mail-Adresse und dem nicht bestätigten Passwort anmeldet.

Achten Sie außerdem darauf, in der Produktion eine HTTPS-URL zu verwenden, damit Ihr Link nicht von zwischengeschalteten Servern abgefangen werden kann.

Anmeldung auf einer Webseite abschließen

Das Format des Deeplinks für E‑Mail-Links ist dasselbe wie das Format, das für Out-of-Band-E‑Mail-Aktionen verwendet wird (E‑Mail-Bestätigung, Passwort zurücksetzen und Widerruf der E‑Mail-Adressänderung). Firebase Auth vereinfacht diese Prüfung mit der isSignInWithEmailLink API, mit der geprüft werden kann, ob ein Link ein Anmeldelink mit E‑Mail-Adresse ist.

Rufen Sie signInWithEmailLink mit der E-Mail-Adresse des Nutzers und dem tatsächlichen E-Mail-Link auf, der den Einmalcode enthält, um die Anmeldung auf der Landingpage abzuschließen.

Web

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 by importing getAdditionalUserInfo
      // and calling it with result:
      // getAdditionalUserInfo(result)
      // You can access the user's profile via:
      // getAdditionalUserInfo(result)?.profile
      // You can check if the user is new or existing:
      // getAdditionalUserInfo(result)?.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

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

Anmeldung in einer mobilen App abschließen

Firebase Authentication verwendet Firebase Hosting, um den E‑Mail-Link an ein Mobilgerät zu senden. Damit die Anmeldung über eine mobile App abgeschlossen werden kann, muss die App so konfiguriert sein, dass sie den eingehenden App-Link erkennt, den zugrunde liegenden Deeplink parst und die Anmeldung dann wie im Web-Ablauf abschließt.

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

Informationen zum Umgang mit der Anmeldung mit E‑Mail-Link in einer Apple-Anwendung finden Sie im Leitfaden für Apple-Plattformen.

Sie können diese Authentifizierungsmethode auch mit einem vorhandenen Nutzer verknüpfen. Wenn sich ein Nutzer beispielsweise zuvor bei einem anderen Anbieter, z. B. mit einer Telefonnummer, authentifiziert hat, kann er diese Anmeldemethode zu seinem bestehenden Konto hinzufügen.

Der Unterschied liegt in der zweiten Hälfte des Vorgangs:

Web

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

// 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 Nutzer mit E-Mail-Link neu zu authentifizieren, bevor ein vertraulicher Vorgang ausgeführt wird.

Web

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

// 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 Ablauf jedoch auf einem anderen Gerät enden könnte, auf dem der ursprüngliche Nutzer nicht angemeldet war, wird er möglicherweise nicht abgeschlossen. In diesem Fall kann dem Nutzer ein Fehler angezeigt werden, um ihn zu zwingen, den Link auf demselben Gerät zu öffnen. Einige Status können im Link übergeben werden, um Informationen zum Vorgangstyp und zur Nutzer-UID bereitzustellen.

Wenn Sie Ihr Projekt am oder nach dem 15. September 2023 erstellt haben, ist der Schutz vor der Aufzählung von E‑Mail-Adressen standardmäßig aktiviert. Diese Funktion verbessert die Sicherheit der Nutzerkonten Ihres Projekts, deaktiviert aber die fetchSignInMethodsForEmail()-Methode, die wir früher für die Implementierung von Abläufen mit dem Identifier als Erstes empfohlen haben.

Sie können den Schutz vor E-Mail-Enumeration für Ihr Projekt zwar deaktivieren, wir raten jedoch davon ab.

Weitere Informationen finden Sie in der Dokumentation zum Schutz vor E-Mail-Enumeration.

Standard-E-Mail-Vorlage für die Anmeldung per Link

Die Standard-E‑Mail-Vorlage enthält einen Zeitstempel im Betreff und im E‑Mail-Text, damit nachfolgende E‑Mails nicht in einem einzigen Thread zusammengefasst werden und der Link ausgeblendet wird.

Diese Vorlage gilt für die folgenden Sprachen:

Code Sprache
ar Arabisch
zh-CN Chinesisch (vereinfacht)
zh-TW Chinesisch (traditionell)
nl Niederländisch
de Englisch
en-GB Englisch (Vereinigtes Königreich)
fr Französisch
de Deutsch
id Indonesisch
it Italienisch
ja Japanisch
ko Koreanisch
pl Polnisch
pt-BR Portugiesisch (Brasilien)
pt-PT Portugiesisch (Portugal)
ru Russisch
es Spanisch
es-419 Spanisch (Lateinamerika)
th Thailändisch

Nächste Schritte

Wenn sich ein Nutzer zum ersten Mal anmeldet, wird ein neues Nutzerkonto erstellt und mit den Anmeldedaten verknüpft, mit denen sich der Nutzer angemeldet hat, also mit dem Nutzernamen und dem Passwort, der Telefonnummer oder den Informationen des Authentifizierungsanbieters. Dieses neue Konto wird als Teil Ihres Firebase-Projekts gespeichert und kann verwendet werden, um einen Nutzer in jeder App in Ihrem Projekt zu identifizieren, unabhängig davon, wie sich der Nutzer anmeldet.

  • In Ihren Apps ist es empfehlenswert, den Authentifizierungsstatus des Nutzers zu ermitteln, indem Sie einen Observer für das Auth-Objekt festlegen. Sie können dann die grundlegenden Profilinformationen des Nutzers aus dem User-Objekt abrufen. Weitere Informationen finden Sie unter Nutzer verwalten.

  • In Ihren Firebase Realtime Database- und Cloud Storage-Sicherheitsregeln können Sie die eindeutige Nutzer-ID des angemeldeten Nutzers aus der auth-Variablen abrufen und damit steuern, auf welche Daten ein Nutzer zugreifen kann.

Sie können Nutzern erlauben, sich mit mehreren Authentifizierungsanbietern in Ihrer App anzumelden, indem Sie Anmeldedaten des Authentifizierungsanbieters mit einem vorhandenen Nutzerkonto verknüpfen.

Rufen Sie signOut auf, um einen Nutzer abzumelden:

Web

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

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

Web

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