Uwierzytelnianie przez telefon

Uwierzytelnianie telefoniczne umożliwia użytkownikom logowanie się w Firebase przy użyciu telefonu jako narzędzia uwierzytelniającego. Do użytkownika (na podany numer telefonu) wysyłany jest SMS z unikalnym kodem. Po autoryzacji kodu użytkownik może zalogować się w Firebase.

Numery telefonów podawane przez użytkowników na potrzeby uwierzytelniania będą przesyłane i przechowywane przez Google w celu ulepszania zapobiegania spamowi i nadużyciom w usługach Google, w tym w Firebase. Deweloperzy powinni przed użyciem usługi logowania za pomocą numeru telefonu w Firebase Authentication uzyskać odpowiednią zgodę użytkowników.

Uwierzytelnianie telefoniczne Firebase nie jest obsługiwane we wszystkich krajach. Więcej informacji znajdziesz w odpowiedziach na najczęstsze pytania.

Konfiguracja

Zanim zaczniesz korzystać z uwierzytelniania za pomocą telefonu, wykonaj te czynności:

  1. Włącz logowanie za pomocą telefonu w konsoli Firebase.
  2. Android: jeśli nie masz jeszcze ustawionego w konsoli Firebase skrótu SHA-1 aplikacji, zrób to. Więcej informacji o znajdowaniu skrótu SHA-1 aplikacji znajdziesz w artykule Uwierzytelnianie klienta.
  3. iOS: w Xcode włącz powiadomienia push w projekcie i upewnij się, że klucz uwierzytelniania APNs jest skonfigurowany z Komunikacją w chmurze Firebase (FCM). Musisz też włączyć tryby działania w tle w przypadku powiadomień zdalnych. Szczegółowe wyjaśnienie tego kroku znajdziesz w dokumentacji Firebase iOS Phone Auth.
  4. Internet: upewnij się, że domena aplikacji została dodana w konsoli Firebase w sekcji Domeny przekierowania OAuth.

Uwaga: logowanie się przy użyciu numeru telefonu jest dostępne tylko na prawdziwych urządzeniach i w internecie. Aby przetestować proces uwierzytelniania na emulatorach urządzeń, zapoznaj się z sekcją Testowanie.

Wykorzystanie

Pakiet SDK usługi Uwierzytelnianie Firebase dla Fluttera udostępnia 2 sposoby logowania użytkownika przy użyciu numeru telefonu. Platformy natywne (np. Android i iOS) zapewniają inne funkcje weryfikacji numeru telefonu niż internet, dlatego na każdej platformie istnieją 2 metody:

  • Platforma natywna: verifyPhoneNumber.
  • Platforma internetowa: signInWithPhoneNumber

Natywne: verifyPhoneNumber

Na platformach natywnych numer telefonu użytkownika musi zostać najpierw zweryfikowany, a następnie użytkownik może się zalogować lub połączyć konto z PhoneAuthCredential.

Najpierw musisz poprosić użytkownika o podanie numeru telefonu. Po podaniu wartości wywołaj metodę verifyPhoneNumber():

await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) {},
  verificationFailed: (FirebaseAuthException e) {},
  codeSent: (String verificationId, int? resendToken) {},
  codeAutoRetrievalTimeout: (String verificationId) {},
);

Musisz obsłużyć 4 osobne wywołania zwrotne. Każde z nich określa sposób aktualizacji interfejsu aplikacji:

  1. verificationCompleted: automatyczna obsługa kodu SMS na urządzeniach z Androidem.
  2. verificationFailed: obsługuje zdarzenia niepowodzenia, takie jak nieprawidłowe numery telefonów lub przekroczenie limitu SMS-ów.
  3. codeSent: funkcja obsługi sytuacji, w której kod został wysłany z Firebase na urządzenie. Służy do wyświetlania użytkownikom prośby o wpisanie kodu.
  4. codeAutoRetrievalTimeout: obsługa przekroczenia limitu czasu, gdy automatyczna obsługa kodu SMS nie powiedzie się.

verificationCompleted

Ten moduł obsługi będzie wywoływany tylko na urządzeniach z Androidem, które obsługują automatyczne rozwiązywanie kodu SMS.

Gdy kod SMS zostanie dostarczony na urządzenie, Android automatycznie go zweryfikuje bez konieczności ręcznego wpisywania przez użytkownika. Jeśli to zdarzenie wystąpi, automatycznie zostanie podany PhoneAuthCredential, którego można użyć do zalogowania się lub powiązania numeru telefonu użytkownika.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) async {
    // ANDROID ONLY!

    // Sign the user in (or link) with the auto-generated credential
    await auth.signInWithCredential(credential);
  },
);

verificationFailed

Jeśli Firebase zwróci błąd, np. z powodu nieprawidłowego numeru telefonu lub przekroczenia limitu SMS-ów w projekcie, do tego modułu obsługi zostanie wysłany błąd FirebaseAuthException. W takim przypadku w zależności od kodu błędu wyświetlisz użytkownikowi komunikat o tym, że coś poszło nie tak.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationFailed: (FirebaseAuthException e) {
    if (e.code == 'invalid-phone-number') {
      print('The provided phone number is not valid.');
    }

    // Handle other errors
  },
);

codeSent

Gdy Firebase wyśle na urządzenie kod SMS, ten moduł obsługi zostanie wywołany z wartościami verificationIdresendToken (wartość resendToken jest obsługiwana tylko na urządzeniach z Androidem, urządzenia z iOS zawsze zwracają wartość null).

Gdy to nastąpi, warto zaktualizować interfejs aplikacji, aby poprosić użytkownika o wpisanie oczekiwanego kodu SMS. Po wpisaniu kodu SMS możesz połączyć identyfikator weryfikacji z kodem SMS, aby utworzyć nowy PhoneAuthCredential:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  codeSent: (String verificationId, int? resendToken) async {
    // Update the UI - wait for the user to enter the SMS code
    String smsCode = 'xxxx';

    // Create a PhoneAuthCredential with the code
    PhoneAuthCredential credential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);

    // Sign the user in (or link) with the credential
    await auth.signInWithCredential(credential);
  },
);

Domyślnie Firebase nie wysyła ponownie nowego SMS-a, jeśli został on niedawno wysłany. Możesz jednak zmienić ten sposób działania, ponownie wywołując metodę verifyPhoneNumber z tokenem ponownego wysyłania jako argumentem forceResendingToken. Jeśli się uda, SMS zostanie wysłany ponownie.

codeAutoRetrievalTimeout

Na urządzeniach z Androidem, które obsługują automatyczne rozwiązywanie kodu SMS, ten moduł obsługi zostanie wywołany, jeśli urządzenie nie rozwiąże automatycznie wiadomości SMS w określonym czasie. Po upływie tego czasu urządzenie nie będzie już próbowało rozwiązywać problemów z żadnymi wiadomościami przychodzącymi.

Domyślnie urządzenie czeka 30 sekund, ale można to zmienić za pomocą argumentu timeout:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  timeout: const Duration(seconds: 60),
  codeAutoRetrievalTimeout: (String verificationId) {
    // Auto-resolution timed out...
  },
);

Sieć: signInWithPhoneNumber

Na platformach internetowych użytkownicy mogą logować się, potwierdzając dostęp do telefonu przez wpisanie kodu SMS wysłanego na podany numer telefonu. Aby zwiększyć bezpieczeństwo i zapobiegać spamowi, użytkownicy są proszeni o potwierdzenie, że są ludźmi, poprzez wypełnienie widżetu Google reCAPTCHA. Po potwierdzeniu wyślemy SMS-a z kodem.

Pakiet SDK Firebase Authentication dla Fluttera domyślnie zarządza widżetem reCAPTCHA, ale w razie potrzeby umożliwia kontrolowanie sposobu jego wyświetlania i konfigurowania. Aby rozpocząć, wywołaj metodę signInWithPhoneNumber z numerem telefonu.

FirebaseAuth auth = FirebaseAuth.instance;

// Wait for the user to complete the reCAPTCHA & for an SMS code to be sent.
ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456');

Wywołanie tej metody spowoduje najpierw wyświetlenie widżetu reCAPTCHA. Użytkownik musi ukończyć test, zanim zostanie wysłany kod SMS. Po zakończeniu tego procesu możesz zalogować użytkownika, podając kod SMS w metodzie confirm w odpowiedzi ConfirmationResult:

UserCredential userCredential = await confirmationResult.confirm('123456');

Podobnie jak w przypadku innych procesów logowania, udane logowanie spowoduje uruchomienie wszystkich odbiorców stanu uwierzytelniania, do których subskrybujesz w aplikacji.

Konfiguracja reCAPTCHA

Widżet reCAPTCHA to w pełni zarządzany proces, który zapewnia bezpieczeństwo aplikacji internetowej.

Drugi argument funkcji signInWithPhoneNumber przyjmuje opcjonalną instancję RecaptchaVerifier, która może służyć do zarządzania widżetem. Domyślnie widżet jest renderowany jako niewidoczny, gdy zostanie wywołany proces logowania. „Niewidoczny” widżet pojawi się jako modalny element na pełnej stronie nad aplikacją.

Możesz jednak wyświetlić widżet wbudowany, który użytkownik musi kliknąć, aby potwierdzić swoją tożsamość.

Aby dodać widżet wbudowany, podaj identyfikator elementu DOM w argumencie container instancji RecaptchaVerifier. Element musi istnieć i być pusty, w przeciwnym razie zostanie zgłoszony błąd. Jeśli nie podasz argumentu container, widżet będzie renderowany jako „niewidoczny”.

ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456', RecaptchaVerifier(
  container: 'recaptcha',
  size: RecaptchaVerifierSize.compact,
  theme: RecaptchaVerifierTheme.dark,
));

Opcjonalnie możesz zmienić rozmiar i motyw, dostosowując argumenty sizetheme, jak pokazano powyżej.

Możesz też nasłuchiwać zdarzeń, np. czy użytkownik ukończył reCAPTCHA, czy reCAPTCHA wygasła lub czy wystąpił błąd:

RecaptchaVerifier(
  onSuccess: () => print('reCAPTCHA Completed!'),
  onError: (FirebaseAuthException error) => print(error),
  onExpired: () => print('reCAPTCHA Expired!'),
);

Testowanie

Firebase obsługuje lokalne testowanie numerów telefonów:

  1. W konsoli Firebase wybierz dostawcę uwierzytelniania „Telefon” i kliknij menu „Numery telefonów do testowania”.
  2. Wpisz nowy numer telefonu (np. +44 7444 555666) i kod testowy (np. 123456).

Jeśli podasz testowy numer telefonu w przypadku metody verifyPhoneNumber lub signInWithPhoneNumber, SMS nie zostanie wysłany. Zamiast tego możesz przekazać kod testu bezpośrednio do PhoneAuthProvider lub za pomocą procedury obsługi wyniku potwierdzenia signInWithPhoneNumber.