Uwierzytelnij się w Firebase za pomocą Email Link na platformach Apple

Możesz użyć uwierzytelniania Firebase, aby zalogować się do użytkownika, wysyłając mu wiadomość e-mail z linkiem, który może kliknąć, aby się zalogować. W tym procesie weryfikowany jest również adres e-mail użytkownika.

Logowanie przez e-mail ma wiele zalet:

  • Rejestracja i logowanie o niskim współczynniku tarcia.
  • Niższe ryzyko ponownego użycia haseł w różnych aplikacjach, co może podważyć bezpieczeństwo nawet dobrze wybranych haseł.
  • Możliwość uwierzytelniania użytkownika przy jednoczesnym weryfikowaniu, czy 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 się bezpiecznie zalogować bez konieczności podawania (lub zapamiętywania) hasła, które 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ło lub federacja), może zostać uaktualniony tak, aby logował się tylko przy użyciu adresu e-mail. Na przykład użytkownik, który zapomniał hasła, nadal może się zalogować bez konieczności resetowania hasła.

Zanim zaczniesz

Użyj Menedżera pakietów Swift, aby zainstalować zależności Firebase i zarządzać nimi.

  1. W Xcode przy otwartym projekcie aplikacji przejdź do pozycji Plik > Dodaj pakiety .
  2. Po wyświetleniu monitu dodaj repozytorium SDK platformy Firebase Apple:
  3.   https://github.com/firebase/firebase-ios-sdk
  4. Wybierz bibliotekę Uwierzytelniania Firebase.
  5. Po zakończeniu Xcode automatycznie rozpocznie rozwiązywanie i pobieranie twoich zależności w tle.

Aby logować użytkowników za pomocą linku w e-mailu, musisz najpierw włączyć dostawcę poczty e-mail i metodę logowania za pomocą łącza e-mail dla swojego projektu Firebase:

  1. W konsoli Firebase otwórz sekcję Auth .
  2. Na karcie Metoda logowania włącz dostawcę poczty e-mail/hasła . Pamiętaj, że logowanie za pomocą poczty e-mail/hasła musi być włączone, aby można było korzystać z logowania za pomocą łącza e-mail.
  3. W tej samej sekcji włącz metodę logowania przez łącze E-mail (logowanie bez hasła) .
  4. Kliknij Zapisz .

Aby zainicjować proces uwierzytelniania, zaprezentuj użytkownikowi interfejs, który prosi użytkownika o podanie adresu e-mail, a następnie wywołaj sendSignInLinkToEmail:actionCodeSettings:completion: aby zażądać od Firebase wysłania linku uwierzytelniającego na adres e-mail użytkownika.

  1. Skonstruuj obiekt ActionCodeSettings , który udostępnia Firebase instrukcje dotyczące tworzenia łącza w wiadomości e-mail. Ustaw następujące pola:

    • url: precyzyjny link do umieszczenia i wszelkie dodatkowe informacje do przekazania. Domena linku musi znajdować się na białej liście domen autoryzowanych w konsoli Firebase, którą można znaleźć przechodząc do zakładki Metoda logowania (Uwierzytelnianie -> Metoda logowania).
    • iOSBundleID i androidPackageName : aplikacje używane po otwarciu linku logowania na urządzeniu z systemem Android lub Apple. Dowiedz się więcej o konfigurowaniu Linków dynamicznych Firebase, aby otwierać linki akcji w wiadomościach e-mail w aplikacjach mobilnych.
    • handleCodeInApp: Ustaw na true. Operacja logowania musi być zawsze zakończona w aplikacji, w przeciwieństwie do innych działań e-mail poza pasmem (resetowanie hasła i weryfikacja adresu e-mail). Dzieje się tak, ponieważ na końcu przepływu oczekuje się, że użytkownik zostanie zalogowany, a jego stan uwierzytelniania zostanie zachowany w aplikacji.
    • dynamicLinkDomain: Jeśli dla projektu zdefiniowano wiele niestandardowych domen łączy dynamicznych, określ, której należy użyć, gdy łącze ma być otwierane za pośrednictwem określonej aplikacji mobilnej (na przykład example.page.link ). W przeciwnym razie pierwsza domena jest wybierana automatycznie.

    Szybki

    let actionCodeSettings = ActionCodeSettings()
    actionCodeSettings.url = URL(string: "https://www.example.com")
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = true
    actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)
    actionCodeSettings.setAndroidPackageName("com.example.android",
                                             installIfNotAvailable: false, minimumVersion: "12")
    

    Cel C

    FIRActionCodeSettings *actionCodeSettings = [[FIRActionCodeSettings alloc] init];
    [actionCodeSettings setURL:[NSURL URLWithString:@"https://www.example.com"]];
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = YES;
    [actionCodeSettings setIOSBundleID:[[NSBundle mainBundle] bundleIdentifier]];
    [actionCodeSettings setAndroidPackageName:@"com.example.android"
                        installIfNotAvailable:NO
                               minimumVersion:@"12"];
    

    Aby dowiedzieć się więcej na temat ActionCodeSettings, zapoznaj się z sekcją Passing State in Email Actions .

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

  3. Wyślij łącze uwierzytelniające na adres e-mail użytkownika i zapisz adres e-mail użytkownika na wypadek, gdyby użytkownik zakończył logowanie do poczty e-mail na tym samym urządzeniu.

    Szybki

    Auth.auth().sendSignInLink(toEmail: email,
                               actionCodeSettings: actionCodeSettings) { error in
      // ...
        if let error = error {
          self.showMessagePrompt(error.localizedDescription)
          return
        }
        // 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.
        UserDefaults.standard.set(email, forKey: "Email")
        self.showMessagePrompt("Check your email for link")
        // ...
    }
    

    Cel C

    [[FIRAuth auth] sendSignInLinkToEmail:email
                       actionCodeSettings:actionCodeSettings
                               completion:^(NSError *_Nullable error) {
      // ...
        if (error) {
          [self showMessagePrompt:error.localizedDescription];
           return;
        }
        // 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.
        [NSUserDefaults.standardUserDefaults setObject:email forKey:@"Email"];
        [self showMessagePrompt:@"Check your email for link"];
        // ...
    }];
    

Obawy dotyczące bezpieczeństwa

Aby uniemożliwić użycie linku do logowania do zalogowania się jako niezamierzony użytkownik lub na niezamierzonym urządzeniu, Firebase Auth wymaga podania adresu e-mail użytkownika podczas kończenia procesu logowania. Aby logowanie się powiodło, ten adres e-mail musi być zgodny z adresem, na który pierwotnie wysłano łącze logowania.

Możesz usprawnić ten przepływ dla użytkowników, którzy otwierają łącze logowania na tym samym urządzeniu, na którym żądają łącza, przechowując ich adresy e-mail lokalnie podczas wysyłania wiadomości e-mail logowania. Następnie użyj tego adresu, aby zakończyć przepływ.

Po zakończeniu logowania wszelkie poprzednie niezweryfikowane mechanizmy logowania zostaną usunięte z użytkownika, a wszelkie istniejące sesje zostaną unieważnione. Na przykład, jeśli ktoś wcześniej utworzył 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ę, która zgłosiła prawo własności i utworzyła to niezweryfikowane konto, ponowne zalogowanie się na to samo konto.

Kończenie logowania w aplikacji mobilnej Apple

Uwierzytelnianie Firebase używa dynamicznych linków Firebase do wysyłania linku w e-mailu na urządzenie mobilne. Aby ukończyć logowanie za pośrednictwem aplikacji mobilnej, aplikacja musi być skonfigurowana do wykrywania przychodzącego łącza do aplikacji, analizowania podstawowego łącza precyzyjnego, a następnie dokończenia logowania.

Firebase Auth używa Firebase Dynamic Links podczas wysyłania linku, który ma zostać otwarty w aplikacji mobilnej. Aby korzystać z tej funkcji, należy skonfigurować Linki dynamiczne w konsoli Firebase.

  1. Włącz Linki dynamiczne Firebase:

    1. W konsoli Firebase otwórz sekcję Linki dynamiczne .
    2. Jeśli nie zaakceptowałeś jeszcze warunków Dynamic Links i utworzyłeś domenę Dynamic Links, zrób to teraz.

      Jeśli masz już utworzoną domenę Dynamic Links, zanotuj to. Domena Dynamic Links zazwyczaj wygląda jak w następującym przykładzie:

      example.page.link

      Ta wartość będzie potrzebna podczas konfigurowania aplikacji Apple lub Android do przechwytywania łącza przychodzącego.

  2. Konfiguracja aplikacji Apple:

    1. Jeśli planujesz obsługiwać te łącza ze swojej aplikacji, identyfikator pakietu należy określić w ustawieniach projektu Firebase Console. Ponadto należy określić identyfikator App Store i Apple Developer Team ID.
    2. Będziesz także musiał skonfigurować swoją domenę obsługi działań e-mail jako domenę powiązaną w możliwościach aplikacji. Domyślnie program obsługi akcji e-mail jest hostowany w domenie, jak w poniższym przykładzie:
      APP_ID.firebaseapp.com
    3. Jeśli planujesz dystrybucję aplikacji na iOS w wersji 8 i starszych, musisz ustawić identyfikator pakietu jako niestandardowy schemat dla przychodzących adresów URL.
    4. Aby uzyskać więcej informacji na ten temat, zapoznaj się z instrukcjami dotyczącymi odbierania łączy dynamicznych platformy Apple .

Po otrzymaniu linku opisanego powyżej sprawdź, czy jest on przeznaczony do uwierzytelniania za pomocą łącza e-mail i zakończ logowanie.

Szybki

if Auth.auth().isSignIn(withEmailLink: link) {
        Auth.auth().signIn(withEmail: email, link: self.link) { user, error in
          // ...
        }
}

Cel C

if ([[FIRAuth auth] isSignInWithEmailLink:link]) {
    [[FIRAuth auth] signInWithEmail:email
                               link:link
                         completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      // ...
    }];
}

Aby dowiedzieć się, jak obsługiwać logowanie za pomocą łącza e-mail w aplikacji na Androida, zapoznaj się z przewodnikiem po systemie Android .

Aby dowiedzieć się, jak obsługiwać logowanie za pomocą łącza e-mail w aplikacji internetowej, zapoznaj się z przewodnikiem internetowym .

Możesz również połączyć tę metodę uwierzytelniania z istniejącym użytkownikiem. Na przykład użytkownik wcześniej uwierzytelniony u innego dostawcy, taki jak numer telefonu, może dodać tę metodę logowania do swojego istniejącego konta.

Różnica byłaby w drugiej połowie operacji:

Szybki

  let credential = EmailAuthCredential.credential(withEmail:email
                                                       link:link)
  Auth.auth().currentUser?.link(with: credential) { authData, error in
    if (error) {
      // And error occurred during linking.
      return
    }
    // The provider was successfully linked.
    // The phone user can now sign in with their phone number or email.
  }

Cel C

  FIRAuthCredential *credential =
      [FIREmailAuthProvider credentialWithEmail:email link:link];
  [FIRAuth auth].currentUser
      linkWithCredential:credential
              completion:^(FIRAuthDataResult *_Nullable result,
                           NSError *_Nullable error) {
    if (error) {
      // And error occurred during linking.
      return;
    }
    // The provider was successfully linked.
    // The phone user can now sign in with their phone number or email.
  }];

Można to również wykorzystać do ponownego uwierzytelnienia użytkownika łącza e-mail przed uruchomieniem poufnej operacji.

Szybki

  let credential = EmailAuthProvider.credential(withEmail:email
                                                       link:link)
  Auth.auth().currentUser?.reauthenticate(with: credential) { authData, error in
    if (error) {
      // And error occurred during re-authentication.
      return
    }
    // The user was successfully re-authenticated.
  }

Cel C

  FIRAuthCredential *credential =
      [FIREmailAuthCredential credentialWithEmail:email link:link];
  [FIRAuth auth].currentUser
      reauthenticateWithCredential:credential
                        completion:^(FIRAuthDataResult *_Nullable result,
                                     NSError *_Nullable error) {
    if (error) {
      // And error occurred during re-authentication
      return;
    }
    // The user was successfully re-authenticated.
  }];

Jednak ponieważ przepływ może zakończyć się na innym urządzeniu, na którym pierwotny użytkownik nie był zalogowany, przepływ ten może nie zostać ukończony. W takim przypadku użytkownikowi może zostać wyświetlony błąd, aby zmusić go do otwarcia łącza na tym samym urządzeniu. W łączu można przekazać pewien stan, aby dostarczyć informacji o typie operacji i identyfikatorze użytkownika.

Jeśli obsługujesz logowanie za pomocą hasła i linku za pomocą poczty e-mail, aby odróżnić metodę logowania dla użytkownika hasła/linku, użyj fetchSignInMethodsForEmail . Jest to przydatne w przypadku przepływów polegających na pierwszym identyfikatorze, w których użytkownik jest najpierw proszony o podanie swojego adresu e-mail, a następnie przedstawiany jest sposób logowania:

Szybki

 // After asking the user for their email.
 Auth.auth().fetchSignInMethods(forEmail: email) { signInMethods, error in
   // This returns the same array as fetchProviders(forEmail:completion:) 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 (error) {
     // Handle error case.
   }
   if (!signInMethods.contains(EmailPasswordAuthSignInMethod)) {
     // User can sign in with email/password.
   }
   if (!signInMethods.contains(EmailLinkAuthSignInMethod)) {
     // User can sign in with email/link.
   }
 }

Cel C

 // After asking the user for their email.
 [FIRAuth auth] fetchSignInMethodsForEmail:email
                                completion:^(NSArray *_Nullable signInMethods,
                                             NSError *_Nullable error) {
   // 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 (error) {
     // Handle error case.
   }
   if (![signInMethods containsObject:FIREmailPasswordAuthSignInMethod]) {
     // User can sign in with email/password.
   }
   if (![signInMethods containsObject:FIREmailLinkAuthSignInMethod]) {
     // User can sign in with email/link.
   }
 }];

Jak opisano powyżej, adres e-mail/hasło i adres e-mail/link są traktowane jako ten sam FIREmailAuthProvider (ten sam PROVIDER_ID ) z różnymi metodami logowania.

Następne kroki

Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i połączone z poświadczeniami — czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami o dostawcy uwierzytelniania — za pomocą których użytkownik się zalogował. To nowe konto jest przechowywane jako część projektu Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w projekcie, niezależnie od tego, jak się on loguje.

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

  • W regułach bezpieczeństwa bazy danych czasu rzeczywistego i usługi Cloud Storage Firebase możesz uzyskać unikalny identyfikator zalogowanego użytkownika ze zmiennej auth i używać go do kontrolowania, do jakich danych użytkownik może uzyskać dostęp.

Możesz zezwolić użytkownikom na logowanie się do Twojej aplikacji przy użyciu wielu dostawców uwierzytelniania, łącząc poświadczenia dostawcy uwierzytelniania z istniejącym kontem użytkownika.

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

Szybki

    let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}
  

Cel C

    NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

Możesz także dodać kod obsługi błędów dla pełnego zakresu błędów uwierzytelniania. Zobacz Obsługa błędów .