Uwierzytelnianie w Firebase za pomocą linku e-mail w JavaScript

Możesz użyć uwierzytelniania Firebase, aby zalogować użytkownika, wysyłając mu e-maila zawierający link, który może kliknąć, aby się zalogować. W trakcie tego procesu użytkownik Adres e-mail również został zweryfikowany.

Logowanie się przez e-maila ma wiele zalet:

  • Rejestracja i logowanie przebiegają sprawnie.
  • Mniejsze ryzyko ponownego użycia hasła w różnych aplikacjach, co może zagrażać bezpieczeństwu nawet dobrze dobrane hasła.
  • Możliwość uwierzytelnienia użytkownika, a jednocześnie weryfikacja, czy użytkownik jest jest uprawnionym właścicielem adresu e-mail.
  • Aby się zalogować, użytkownik musi mieć tylko dostępne konto e-mail. Brak własności elementu Numer telefonu lub konto w mediach społecznościowych są wymagane.
  • Użytkownik może logować się bezpiecznie bez konieczności podawania (lub zapamiętania) co może być uciążliwe na urządzeniu mobilnym.
  • Istniejący użytkownik, który wcześniej zalogował się przy użyciu identyfikatora e-mail (hasła) lub sfederowanego) może przejść na wyższą wersję, aby logować się za pomocą samego adresu e-mail. Na przykład plik użytkownik, który nie pamięta hasła, może się zalogować bez konieczności resetować hasło.

Zanim zaczniesz

Skopiuj fragment kodu inicjowania z sekcji Firebase konsolę do swojego projektu, jak opisano w sekcji . Dodaj Firebase do projektu JavaScript.

Aby zalogować użytkowników za pomocą linku w e-mailu, musisz najpierw włączyć dostawcę poczty e-mail Metoda logowania za pomocą linku wysłanego e-mailem do projektu Firebase:

  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie.
  2. Na karcie Metoda logowania włącz dostawcę E-mail/hasła. Notatka że logowanie za pomocą adresu e-mail za pomocą linku wymaga włączenia logowania za pomocą adresu e-mail i hasła.
  3. W tej samej sekcji włącz logowanie się przy użyciu opcji Link w e-mailu (logowanie bez hasła). .
  4. Kliknij Zapisz.

Aby zainicjować proces uwierzytelniania, przekaż użytkownikowi interfejs, który prosi użytkownika o podanie adresu e-mail, a następnie sendSignInLinkToEmail, aby poprosić Firebase o wysłanie linku uwierzytelniającego do adres e-mail użytkownika.

  1. Utwórz obiekt ActionCodeSettings, który udostępnia Firebase instrukcje tworzenia linku do e-maila. Ustaw wartości w tych polach:

    • url: precyzyjny link do umieszczenia i wszystkie dodatkowe stany do przekazania. Domena linku należy dodać do listy w konsoli Firebase autoryzowane domeny, które można znaleźć na karcie Metoda logowania. (Uwierzytelnianie -> Ustawienia).
    • android i ios: aplikacje, z których będą korzystać po otwarciu linku logowania na urządzeniu urządzenie z Androidem lub firmy Apple. Dowiedz się więcej o tym, Skonfiguruj Linki dynamiczne Firebase otwierać w aplikacjach mobilnych linki do działań w e-mailach.
    • handleCodeInApp: ustaw wartość prawda. Operacja logowania musi zawsze wykonane w aplikacji w przeciwieństwie do innych spoza zakresu działań związanych z e-mailami (hasło resetowanie urządzenia i potwierdzanie adresu e-mail). To dlatego, że na końcu cyklu użytkownik powinien być zalogowany, a jego stan uwierzytelniania utrzymywał się przez aplikację.
    • dynamicLinkDomain: gdy zdefiniowano wiele niestandardowych domen linków dynamicznych w projekcie, określ, który z nich ma być używany, gdy link ma być otwierany określoną aplikację mobilną (np. example.page.link). W przeciwnym razie Pierwsza domena jest wybierana automatycznie.

      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'
        },
        dynamicLinkDomain: 'example.page.link'
      };

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

    Więcej informacji o ActionCodeSettings znajdziesz tutaj Stan udanego działania e-maili .

  2. Poproś użytkownika o podanie adresu e-mail.

  3. Wyślij link uwierzytelniania na adres e-mail użytkownika i zapisz jego adres e-mail. w sytuacji, gdy użytkownik zaloguje się przez e-maila na tym samym urządzeniu.

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

Potencjalne problemy z bezpieczeństwem

Zapobieganie używaniu linku logowania do logowania się jako niezamierzony użytkownik lub po jego włączeniu niezamierzonym urządzeniem, Uwierzytelnianie Firebase wymaga podania adresu e-mail użytkownika podany podczas logowania. Aby można było się zalogować, ten adres e-mail musi odpowiadać adresowi, na który został pierwotnie wysłany link umożliwiający zalogowanie się.

Możesz usprawnić ten proces w przypadku użytkowników, którzy po kliknięciu linku logowania urządzenia, z którego użytkownik poprosi o link, zapisując swój adres e-mail lokalnie – dla instancji za pomocą localStorage lub plików cookie – podczas wysyłania e-maila logowania. Następnie: użyj tego adresu, aby zakończyć proces. Nie przekazuj adresu e-mail użytkownika w parametrach adresu URL przekierowania i nie używaj go ponownie jako może to umożliwić wstrzykiwanie sesji.

Po zakończeniu logowania każdy wcześniej niezweryfikowany mechanizm logowania zostanie wyłączony. zostanie usunięte z konta użytkownika, a wszystkie istniejące sesje zostaną unieważnione. Na przykład jeśli ktoś wcześniej utworzył niezweryfikowane konto z tym samym adres e-mail i hasło zostaną usunięte, aby zapobiec Użytkownik podszywający się pod Ciebie, który zgłosił prawo własności i utworzył niezweryfikowane konto z zaloguj się ponownie przy użyciu niezweryfikowanego adresu e-mail i hasła.

Upewnij się też, że używasz adresu URL HTTPS w wersji produkcyjnej. Dzięki temu link nie będzie potencjalnie przechwycone przez serwery pośrednie.

Logowanie się na stronie internetowej

Format precyzyjnego linku w e-mailu jest taki sam jak format używany w przypadku pozapasmowych działań e-mailowych (weryfikacja adresu e-mail, resetowanie hasła i unieważnienie zmiany adresu e-mail). Uwierzytelnianie Firebase upraszcza tę weryfikację, udostępniając interfejs isSignInWithEmailLink API aby sprawdzić, czy link prowadzi do logowania za pomocą linku e-mail.

Aby zalogować się na stronie docelowej, zadzwoń pod numer signInWithEmailLink i podaj adres e-mail użytkownika oraz rzeczywisty link e-mail zawierający kod jednorazowy.

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

Logowanie się w aplikacji mobilnej

Uwierzytelnianie Firebase używa Linków dynamicznych Firebase do wysyłania linku e-mail do urządzenia mobilnego. W celu zalogowania się za pomocą aplikacji mobilnej aplikacja należy skonfigurować, aby wykrywać przychodzący link aplikacji, przeanalizować i zaloguj się jako precyzyjny link.

Aby dowiedzieć się więcej o obsłudze logowania za pomocą linku e-mail na urządzeniu z Androidem aplikacji znajdziesz w przewodniku po Androidzie.

Aby dowiedzieć się więcej o obsłudze logowania za pomocą linku e-mail na urządzeniu Apple aplikacji znajdziesz w przewodniku po platformach Apple.

Możesz też powiązać tę metodę uwierzytelniania z istniejącym użytkownikiem. Przykład: użytkownik został wcześniej uwierzytelniony u innego dostawcy, np. przy użyciu numeru telefonu; mogą dodać tę metodę logowania do swojego istniejącego konta.

Różnica będzie widoczna w drugiej połowie operacji:

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

W ten sposób można też ponownie uwierzytelnić użytkownika korzystającego z linku e-mail przed uruchomieniem poufnej operacji.

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

Ponieważ przepływ może jednak skończyć się na innym urządzeniu, na którym pierwotny użytkownik Użytkownik nie jest zalogowany, ten proces mógł nie zostać ukończony. W takim przypadku błąd może ma być wyświetlana użytkownikowi, aby zmusić go do otwarcia linku na tym samym urządzeniu. Niektóre stan można przekazać w linku w celu podania informacji o typie operacji oraz identyfikator UID użytkownika.

Jeśli Twój projekt został utworzony 15 września 2023 r. lub później, wyliczanie adresów e-mail ochrona jest domyślnie włączona. Ta funkcja zwiększa bezpieczeństwo kont użytkowników projektu, ale wyłącza fetchSignInMethodsForEmail() Metoda, którą mieliśmy wcześniej zalecać do implementacji przepływów skoncentrowanych na identyfikatorze.

Chociaż możesz wyłączyć ochronę wyliczania adresów e-mail w projekcie, takiego działania.

Zapoznaj się z dokumentacją dotyczącą ochrony przed wyliczeniem adresów e-mail .

Domyślny szablon e-maila dotyczącego logowania za pomocą linku

Domyślny szablon e-maila zawiera sygnaturę czasową w temacie i treści e-maila aby kolejne e-maile nie były zwijane w jeden wątek z linkiem w którymś z nich się nie ukrywasz.

Ten szablon dotyczy tych języków:

Kod Język
ar arabski
zh-CN chiński (uproszczony)
zh-TW chiński (tradycyjny)
niderlandzki niderlandzki
en angielski
en-GB angielski (Wlk. Brytania)
fr francuski
de niemiecki
id Indonezyjski
jego włoski
ja japoński
ko koreański
pl polski
pt-BR portugalski (Brazylia)
pt-PT portugalski (Portugalia)
ru rosyjski
es hiszpański
ES-419 hiszpański (Ameryka Łacińska)
th tajski

Dalsze kroki

Gdy użytkownik zaloguje się po raz pierwszy, tworzone jest nowe konto użytkownika. powiązane z danymi logowania, czyli z nazwą użytkownika, hasłem i numerem telefonu, numer telefonu lub informacje o dostawcy uwierzytelniania – użytkownik zalogowany. Ten nowy jest przechowywane w ramach projektu Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w projekcie, niezależnie od tego, jak się loguje.

  • Aby poznać stan uwierzytelniania użytkownika w swoich aplikacjach, ustaw obserwatora na obiekcie Auth. Dzięki temu możesz uzyskać dane użytkownika podstawowych informacji o profilu z obiektu User. Zobacz Zarządzanie użytkownikami

  • Na liście Firebase Realtime Database i Cloud Storage regułami zabezpieczeń, pobierz ze zmiennej auth unikalny identyfikator zalogowanego użytkownika, i używać ich do kontrolowania, do jakich danych użytkownik ma dostęp.

Możesz zezwolić użytkownikom na logowanie się w aplikacji przy użyciu wielokrotnego uwierzytelniania. dostawców, łącząc dane logowania dostawcy uwierzytelniania z istniejącego konta użytkownika.

Aby wylogować użytkownika, wywołaj signOut:

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