Uwierzytelnianie w Firebase za pomocą linków e-mail

Możesz użyć uwierzytelniania Firebase, aby zalogować użytkownika, wysyłając mu e-maila z linkiem, który może kliknąć, aby się zalogować. Podczas procesu weryfikacji zweryfikowany jest też adres e-mail użytkownika.

Logowanie się przez e-maila ma wiele zalet:

  • Rejestracja i logowanie przebiegają sprawnie.
  • Mniejsze ryzyko ponownego użycia tego samego hasła w różnych aplikacjach, co może zagrażać bezpieczeństwu nawet dobrze dobranych haseł.
  • Możliwość uwierzytelnienia użytkownika, a jednocześnie potwierdzanie, że jest on prawowitym właścicielem adresu e-mail.
  • Aby się zalogować, użytkownik potrzebuje tylko dostępnego konta e-mail. Nie jest wymagane posiadanie numeru telefonu ani konta w mediach społecznościowych.
  • Użytkownik może logować się bezpiecznie bez konieczności podawania (lub zapamiętywania) hasła, co może być uciążliwe na urządzeniu mobilnym.
  • Istniejące konto użytkownika, które wcześniej logowało się przy użyciu identyfikatora e-mail (hasła lub konta sfederowanego), można przejść na wyższą wersję, aby logować się przy użyciu samego adresu e-mail. Na przykład użytkownik, który nie pamięta hasła, może się zalogować bez konieczności resetowania hasła.

Zanim zaczniesz

  1. W razie potrzeby wykonaj czynności opisane w przewodniku Pierwsze kroki.

  2. Włącz logowanie się w projekcie Firebase za pomocą linku e-mail.

    Aby logować użytkowników za pomocą linku w e-mailu, musisz najpierw włączyć w projekcie Firebase metodę logowania Dostawca poczty e-mail i metoda logowania za pomocą linku w e-mailu:

    1. W konsoli Firebase otwórz sekcję Uwierzytelnianie.
    2. Na karcie Metoda logowania włącz dostawcę E-mail/hasła. Aby korzystać z logowania za pomocą linku e-mail, musisz włączyć logowanie za pomocą adresu e-mail i hasła.
    3. W tej samej sekcji włącz metodę logowania Link e-mail (logowanie bez hasła).
    4. Kliknij Zapisz.

Aby zainicjować proces uwierzytelniania, skonfiguruj interfejs, aby poprosić użytkownika o podanie adresu e-mail, a następnie wywołaj sendSignInLinkToEmail(), aby poprosić Firebase o wysłanie linku uwierzytelniającego na adres e-mail użytkownika.

  1. Utwórz obiekt ActionCodeSettings, który dostarcza 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 musi znajdować się na białej liście na liście autoryzowanych domen w konsoli Firebase. Aby ją znaleźć, przejdź na kartę Metoda logowania (Uwierzytelnianie -> Metoda logowania). Jeśli aplikacja nie jest zainstalowana na urządzeniu i nie udało się jej zainstalować, link przekieruje użytkownika pod ten adres URL.

    • androidPackageName i IOSBundleId: aplikacje używane po otwarciu linku logowania na urządzeniu z Androidem lub iOS. Dowiedz się więcej o tym, jak skonfigurować Linki dynamiczne Firebase pod kątem otwierania linków do działań w e-mailach w aplikacjach mobilnych.

    • handleCodeInApp: ustaw wartość true. Operacja logowania musi być zawsze wykonywana w aplikacji, w przeciwieństwie do innych pozapasmowych działań związanych z pocztą e-mail (resetowanie hasła i potwierdzanie adresu e-mail). Dzieje się tak, ponieważ na koniec procesu użytkownik powinien być zalogowany, a jego stan uwierzytelniania musi pozostać w aplikacji.

    • dynamicLinkDomain: jeśli w projekcie zdefiniowano wiele niestandardowych domen linków dynamicznych, określ, która z nich ma być używana, gdy link ma być otwierany przez określoną aplikację mobilną (na przykład example.page.link). W przeciwnym razie automatycznie zostanie wybrana pierwsza domena.

    var acs = ActionCodeSettings(
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true
        handleCodeInApp: true,
        iOSBundleId: 'com.example.ios',
        androidPackageName: 'com.example.android',
        // installIfNotAvailable
        androidInstallApp: true,
        // minimumVersion
        androidMinimumVersion: '12');
    
  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 na wypadek, gdyby użytkownik logował się za pomocą adresu e-mail na tym samym urządzeniu.

    var emailAuth = 'someemail@domain.com';
    FirebaseAuth.instance.sendSignInLinkToEmail(
            email: emailAuth, actionCodeSettings: acs)
        .catchError((onError) => print('Error sending email verification $onError'))
        .then((value) => print('Successfully sent email verification'));
    });
    

Potencjalne problemy z bezpieczeństwem

Aby zapobiec użyciu linku logowania do zalogowania się jako niezamierzony użytkownik lub na niewłaściwym urządzeniu, Uwierzytelnianie Firebase wymaga podania adresu e-mail użytkownika podczas logowania się. Aby logowanie się powiodło, ten adres e-mail musi być zgodny z adresem, na który pierwotnie przesłano link.

Możesz usprawnić ten proces w przypadku użytkowników, którzy otwierają link logowania na tym samym urządzeniu, na tym samym urządzeniu, zapisując swój adres e-mail lokalnie – na przykład za pomocą SharedPreferences – gdy wysyłasz e-maila logowania. Następnie użyj tego adresu do dokończenia procesu. Nie przekazuj adresu e-mail użytkownika w parametrach przekierowania ani nie używaj go ponownie, ponieważ może to umożliwić wstrzykiwanie sesji.

Po zakończeniu logowania wszystkie wcześniejsze niezweryfikowane mechanizmy logowania zostaną usunięte z konta użytkownika, a wszystkie istniejące sesje zostaną unieważnione. Jeśli na przykład ktoś utworzył wcześniej niezweryfikowane konto z tym samym adresem e-mail i hasłem, hasło użytkownika zostanie usunięte, aby uniemożliwić osobie podszywającej się pod inną osobę, która zgłosiła prawo własności i utworzyła niezweryfikowane konto ponownie, za pomocą niezweryfikowanego adresu e-mail i hasła.

Upewnij się też, że w środowisku produkcyjnym używasz adresu URL HTTPS, aby zapobiec potencjalnemu przechwyceniu linku przez serwery pośrednie.

Uwierzytelnianie Firebase używa Linków dynamicznych Firebase do wysyłania linku e-mail na urządzenie mobilne. Aby można było zalogować się za pomocą aplikacji mobilnej, należy skonfigurować aplikację tak, aby wykrywała przychodzący link do aplikacji, przeanalizowała precyzyjny link i dokończyła logowanie.

  1. Skonfiguruj aplikację pod kątem otrzymywania linków dynamicznych w technologii Flutter w tym przewodniku.

  2. W module obsługi linków sprawdź, czy link służy do uwierzytelniania go w e-mailu, a jeśli tak, dokończ proces logowania.

    // Confirm the link is a sign-in with email link.
    if (FirebaseAuth.instance.isSignInWithEmailLink(emailLink)) {
      try {
        // The client SDK will parse the code from the link for you.
        final userCredential = await FirebaseAuth.instance
            .signInWithEmailLink(email: emailAuth, emailLink: emailLink);
    
        // You can access the new user via userCredential.user.
        final emailAddress = userCredential.user?.email;
    
        print('Successfully signed in with email link!');
      } catch (error) {
        print('Error signing in with email link.');
      }
    }
    

Możesz też powiązać tę metodę uwierzytelniania z istniejącym użytkownikiem. Na przykład użytkownik, który wcześniej uwierzytelnił się u innego dostawcy (np. przy użyciu numeru telefonu), może dodać tę metodę logowania do swojego istniejącego konta.

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

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.linkWithCredential(authCredential);
} catch (error) {
    print("Error linking emailLink credential.");
}

W ten sposób możesz też ponownie uwierzytelnić użytkownika powiązanego z linkiem e-mail przed uruchomieniem operacji poufnej.

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.reauthenticateWithCredential(authCredential);
} catch (error) {
    print("Error reauthenticating credential.");
}

Proces ten może jednak nie zostać ukończony na innym urządzeniu, na którym pierwotny użytkownik nie był zalogowany. W takim przypadku może wyświetlić się komunikat o błędzie, który będzie wymuszał na nim otwarcie linku na tym samym urządzeniu. W linku można przekazać informacje o typie działania i identyfikatorze UID użytkownika.

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

Chociaż możesz wyłączyć ochronę wyliczania adresów e-mail w projekcie, nie zalecamy tego.

Więcej informacji znajdziesz w dokumentacji dotyczącej ochrony przed wyliczeniem adresów e-mail.

Dalsze kroki

Gdy użytkownik utworzy nowe konto, będzie ono przechowywane w ramach Twojego projektu Firebase i będzie można go używać do identyfikowania użytkownika we wszystkich aplikacjach w Twoim projekcie, niezależnie od użytej metody logowania.

W aplikacjach możesz uzyskać podstawowe informacje o profilu użytkownika z obiektu User. Zobacz Zarządzanie użytkownikami.

W bazie danych czasu rzeczywistego Firebase i regułach zabezpieczeń Cloud Storage możesz uzyskać ze zmiennej auth unikalny identyfikator zalogowanego użytkownika i użyć go do kontrolowania, do jakich danych użytkownik ma dostęp.

Możesz zezwolić użytkownikom na logowanie się w aplikacji przy użyciu różnych dostawców uwierzytelniania, łącząc dane logowania dostawcy uwierzytelniania) z istniejącym kontem użytkownika.

Aby wylogować użytkownika, zadzwoń pod numer signOut():

await FirebaseAuth.instance.signOut();