Uwierzytelnianie w Firebase za pomocą linku e-mail na platformach Apple

Usługa Uwierzytelnianie Firebase umożliwia logowanie użytkowników przez wysyłanie im e-maili z linkiem, który mogą kliknąć, aby się zalogować. W tym procesie weryfikowany jest też adres e-mail użytkownika.

Logowanie za pomocą adresu e-mail ma wiele korzyści:

  • Bezproblemowa rejestracja i logowanie.
  • Mniejsze ryzyko ponownego użycia haseł w różnych aplikacjach, co może osłabić bezpieczeństwo nawet dobrze dobranych haseł.
  • Możliwość uwierzytelniania użytkownika przy jednoczesnej weryfikacji, czy jest on prawowitym właścicielem adresu e-mail.
  • Aby się zalogować, użytkownik potrzebuje tylko dostępnego konta e-mail. Nie musisz być właścicielem numeru telefonu ani konta w mediach społecznościowych.
  • Użytkownik może bezpiecznie zalogować się bez konieczności podawania (lub zapamiętywania) hasła, co może być uciążliwe na urządzeniu mobilnym.
  • Dotychczasowy użytkownik, który wcześniej logował się za pomocą identyfikatora e-mail (hasła lub logowania sfederowanego), może przejść na logowanie się tylko przy użyciu adresu e-mail. Na przykład użytkownik, który zapomniał hasła, może się zalogować bez konieczności jego resetowania.

Zanim zaczniesz

Do instalowania zależności Firebase i zarządzania nimi używaj Swift Package Manager.

  1. W Xcode otwórz projekt aplikacji i kliknij File > Add Packages (Plik > Dodaj pakiety).
  2. Gdy pojawi się odpowiedni komunikat, dodaj repozytorium pakietu SDK Firebase na platformy Apple:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Wybierz bibliotekę Firebase Authentication.
  5. Dodaj flagę -ObjC do sekcji Other Linker Flags (Inne flagi linkera) w ustawieniach kompilacji elementu docelowego.
  6. Po zakończeniu Xcode automatycznie zacznie przetwarzać i pobierać 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ą linku w e-mailu w projekcie w Firebase:

  1. W konsoli Firebase otwórz Bezpieczeństwo > Uwierzytelnianie.

  2. Na karcie Metoda logowania włącz dostawcę logowania E-mail/hasło. Pamiętaj, że aby korzystać z logowania za pomocą linku w e-mailu, musisz włączyć logowanie za pomocą adresu e-mail i hasła.

  3. W tej samej sekcji włącz dostawcę Link w e-mailu (logowanie bez hasła).

  4. Kliknij Zapisz.

Aby rozpocząć proces uwierzytelniania, wyświetl użytkownikowi interfejs, który poprosi go o podanie adresu e-mail, a następnie wywołaj sendSignInLink, aby poprosić Firebase o wysłanie linku do uwierzytelniania na adres e-mail użytkownika.

  1. Utwórz obiekt ActionCodeSettings, który zawiera instrukcje dla Firebase dotyczące tworzenia linku w e-mailu. Ustaw wartości w tych polach:

    • url: precyzyjny link do umieszczenia i wszelkie dodatkowe informacje o stanie, które mają zostać przekazane. Jeśli jeszcze tego nie zrobiono, dodaj domenę do listy autoryzowanych domen:

      1. W konsoli Firebase otwórz Zabezpieczenia > Uwierzytelnianie > karta Ustawienia.

      2. W sekcji Autoryzowane domeny kliknij Dodaj domenę i dodaj swoją domenę.

    • iOSBundleID i androidPackageName: pomaga Firebase Authentication określić, czy ma utworzyć link tylko do internetu czy link mobilny, który zostanie otwarty na urządzeniu z Androidem lub Apple.
    • handleCodeInApp: ustaw na wartość „true”. Proces logowania musi zawsze być przeprowadzany w aplikacji, w przeciwieństwie do innych działań wykonywanych poza pasmem za pomocą e-maila (resetowanie hasła i weryfikacja adresu e-mail). Dzieje się tak, ponieważ na końcu procesu użytkownik powinien być zalogowany, a jego stan uwierzytelniania powinien być zachowany w aplikacji.
    • linkDomain: jeśli w projekcie zdefiniowano niestandardowe domeny linków Hosting, określ, której z nich należy użyć, gdy link ma być otwierany przez konkretną aplikację mobilną. W przeciwnym razie automatycznie zostanie wybrana domena domyślna (np. PROJECT_ID.firebaseapp.com).
    • dynamicLinkDomain: wycofano. Nie podawaj tego parametru.

    Swift

    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")

    Objective-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"];

    Więcej informacji o ActionCodeSettings znajdziesz w sekcji Przekazywanie stanu w działaniach związanych z e-mailami.

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

  3. Wyślij link uwierzytelniający na adres e-mail użytkownika i zapisz ten adres na wypadek, gdyby użytkownik dokończył logowanie przez e-mail na tym samym urządzeniu.

    Swift

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

    Objective-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"];
        // ...
    }];

Potencjalne problemy z bezpieczeństwem

Aby zapobiec użyciu linku do logowania w celu zalogowania się jako nieodpowiedni użytkownik lub na nieodpowiednim 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 został wysłany link do logowania.

Możesz uprościć ten proces dla użytkowników, którzy otwierają link do logowania na tym samym urządzeniu, na którym o niego proszą. W tym celu zapisz lokalnie ich adres e-mail, gdy wysyłasz e-maila z linkiem do logowania. Następnie użyj tego adresu, aby dokończyć proces.

Po zakończeniu logowania wszystkie poprzednie niezweryfikowane mechanizmy logowania zostaną usunięte z konta użytkownika, a wszystkie dotychczasowe sesje zostaną unieważnione. Jeśli na przykład 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ć podszywającemu się pod niego użytkownikowi, który zgłosił prawo własności i utworzył to niezweryfikowane konto, ponowne zalogowanie się na to samo konto.

Kończenie logowania w aplikacji mobilnej Apple

Firebase Authentication używa Firebase Hosting, aby wysłać link do e-maila na urządzenie mobilne. Aby dokończyć logowanie za pomocą aplikacji mobilnej, musi ona być skonfigurowana tak, aby wykrywać przychodzący link do aplikacji, analizować precyzyjny link i dokończyć logowanie. Więcej informacji o tym, jak to zrobić, znajdziesz w artykule o linkach uniwersalnych i powiązanych domenach w iOS.

Skonfiguruj funkcję Firebase Hosting

Firebase Authentication używa domen Firebase Hosting podczas tworzenia i wysyłania linku, który ma być otwierany w aplikacji mobilnej. Domyślna Firebase Hosting domena została już skonfigurowana.

  1. Skonfiguruj domeny Firebase Hosting:

    W konsoli Firebase otwórz Hosting i usługi bezserwerowe > Hosting.

    • Jeśli chcesz użyć domyślnej domeny w przypadku linku w e-mailu, który otwiera się w aplikacjach mobilnych, przejdź do domyślnej witryny i zanotuj domyślną domenę Hosting. Domyślna domena Hosting zwykle wygląda tak: PROJECT_ID.firebaseapp.com.

      Będzie on potrzebny podczas konfigurowania aplikacji do przechwytywania przychodzącego linku.

    • Jeśli chcesz użyć niestandardowej domeny w przypadku linku do e-maila, możesz zarejestrować ją w Firebase Hosting i użyć jej jako domeny linku.

  2. Konfigurowanie aplikacji Apple:

    Wybraną domenę musisz skonfigurować jako powiązaną domenę w przypadku linków do aplikacji. Aby skonfigurować uprawnienie w aplikacji, otwórz w Xcode kartę Signing & Capabilities (Podpisywanie i możliwości) i dodaj do możliwości Powiązane domeny domeny Hosting Firebase z poprzedniego kroku. Jeśli używasz domeny domyślnej Firebase Hosting, będzie to applinks:PROJECT_ID.firebaseapp.com.

    Więcej informacji znajdziesz w artykule Obsługa powiązanych domen na stronie dokumentacji Apple.

Po otrzymaniu linku w sposób opisany powyżej sprawdź, czy służy on do uwierzytelniania za pomocą linku w e-mailu, i zaloguj się.

Swift

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

Objective-C

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

Informacje o tym, jak obsługiwać logowanie za pomocą linku w e-mailu w aplikacji na Androida, znajdziesz w przewodniku po Androidzie.

Aby dowiedzieć się, jak obsługiwać logowanie za pomocą linku w e-mailu w aplikacji internetowej, zapoznaj się z przewodnikiem po internecie.

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

Różnica wystąpi w drugiej połowie operacji:

Swift

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

Objective-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 go też użyć do ponownego uwierzytelnienia użytkownika linku e-mail przed wykonaniem operacji wymagającej szczególnej ochrony.

Swift

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

Objective-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 proces może zakończyć się na innym urządzeniu, na którym pierwotny użytkownik nie był zalogowany, więc może nie zostać ukończony. W takim przypadku użytkownikowi może zostać wyświetlony błąd, który zmusi go do otwarcia linku na tym samym urządzeniu. W linku można przekazać pewien stan, aby podać informacje o typie operacji i identyfikatorze użytkownika.

Przed wprowadzeniem Firebase Authenticationpakietu iOS SDK w wersji 11.8.0 funkcja logowania za pomocą linku w e-mailu korzystała z Firebase Dynamic Links, aby otwierać linki do logowania w odpowiedniej aplikacji. Te linki weryfikacyjne są wycofywane, ponieważ Firebase Dynamic Links zostanie wyłączony 25 sierpnia 2025 roku.

Jeśli Twoja aplikacja korzysta ze starych linków, przenieś ją na nowy system oparty na Firebase Hosting.

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

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

Więcej informacji znajdziesz w artykule Włączanie i wyłączanie ochrony przed wyliczaniem adresów e-mail.

Dalsze kroki

Po pierwszym zalogowaniu się użytkownika tworzone jest nowe konto użytkownika, które jest powiązane z danymi logowania, 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 w ramach projektu w Firebase i może służyć do identyfikowania użytkownika we wszystkich aplikacjach w projekcie, niezależnie od sposobu logowania.

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

  • W Firebase Realtime Database i Cloud Storage regułach bezpieczeństwa możesz pobrać unikalny identyfikator zalogowanego użytkownika ze zmiennej auth i użyć go do kontrolowania, do jakich danych użytkownik może mieć dostęp.

Możesz zezwolić użytkownikom na logowanie się w aplikacji za pomocą wielu dostawców uwierzytelniania, łącząc dane logowania dostawcy uwierzytelniania z istniejącym kontem użytkownika.

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

Swift

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

Objective-C

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

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