Uwierzytelnianie w Firebase za pomocą numeru telefonu przy użyciu JavaScriptu

Za pomocą Uwierzytelniania Firebase możesz zalogować użytkownika, wysyłając na jego telefon SMS-a. Użytkownik loguje się za pomocą jednorazowego kodu zawartego w wiadomości SMS.

Najprostszym sposobem na dodanie do aplikacji funkcji logowania się za pomocą numeru telefonu jest skorzystanie z FirebaseUI, który zawiera widżet logowania. Zawiera on procedury logowania przy użyciu numeru telefonu, a także logowanie z użyciem hasła i logowanie sfederowane. W tym dokumencie opisujemy, jak wdrożyć proces logowania się za pomocą numeru telefonu za pomocą pakietu SDK Firebase.

Zanim zaczniesz

Skopiuj do swojego projektu fragment kodu inicjowania z konsoli Firebase zgodnie z opisem w sekcji Dodawanie Firebase do projektu JavaScript.

Potencjalne problemy z bezpieczeństwem

Uwierzytelnianie przy użyciu samego numeru telefonu, choć jest wygodne, jest mniej bezpieczne niż inne dostępne metody, ponieważ można łatwo przenieść numer telefonu między użytkownikami. Poza tym na urządzeniach z wieloma profilami każdy użytkownik, który może otrzymywać SMS-y, może zalogować się na konto, używając numeru telefonu.

Jeśli w aplikacji korzystasz z logowania się za pomocą numeru telefonu, zaoferuj tę funkcję wraz z bezpieczniejszymi metodami logowania i poinformuj użytkowników o konsekwencjach związanych z bezpieczeństwem logowania się za pomocą numeru telefonu.

Włącz logowanie się za pomocą numeru telefonu w projekcie Firebase

Aby logować użytkowników przez SMS-y, musisz najpierw włączyć w projekcie Firebase metodę logowania się za pomocą numeru telefonu:

  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie.
  2. Na stronie Metoda logowania włącz metodę logowania Numer telefonu.
  3. Jeśli domeny hostującej Twoją aplikację nie ma w sekcji Domeny przekierowań OAuth na tej samej stronie, dodaj swoją domenę. Pamiętaj, że localhost nie może być domeną hostowaną na potrzeby uwierzytelniania przez telefon.

Limit próśb o zalogowanie się przy użyciu numeru telefonu w Firebase jest wystarczająco wysoki, aby nie miał on wpływu na większość aplikacji. Jeśli jednak chcesz logować się bardzo dużej liczbie użytkowników za pomocą uwierzytelniania telefonicznego, konieczne może być przejście na wyższy abonament. Przejdź na stronę cen.

Konfigurowanie weryfikatora reCAPTCHA

Zanim będzie można logować użytkowników za pomocą ich numerów telefonów, musisz skonfigurować weryfikatora reCAPTCHA w Firebase. Firebase korzysta z reCAPTCHA, aby zapobiegać nadużyciom, na przykład przez zapewnienie, że żądanie weryfikacji numeru telefonu pochodzi z jednej z dozwolonych domen aplikacji.

Nie musisz ręcznie konfigurować klienta reCAPTCHA. Gdy używasz obiektu RecaptchaVerifier pakietu Firebase SDK, Firebase automatycznie tworzy i obsługuje wszystkie niezbędne klucze klienta i tajne klucze klienta.

Obiekt RecaptchaVerifier obsługuje niewidoczną funkcję reCAPTCHA, która często umożliwia weryfikację użytkownika bez konieczności wykonywania żadnej czynności, a także widżet reCAPTCHA, który zawsze wymaga interakcji użytkownika.

Bazową wyrenderowaną usługę reCAPTCHA można zlokalizować zgodnie z preferencjami użytkownika, aktualizując kod języka w instancji Auth przed renderowaniem reCAPTCHA. Wspomniana powyżej lokalizacja będzie miała również zastosowanie do wiadomości SMS z kodem weryfikacyjnym wysłanej do użytkownika.

Web

import { getAuth } from "firebase/auth";

const auth = getAuth();
auth.languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// auth.useDeviceLanguage();

Web

firebase.auth().languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

Używaj niewidocznej usługi reCAPTCHA

Aby użyć niewidocznego obiektu reCAPTCHA, utwórz obiekt RecaptchaVerifier z parametrem size ustawionym na invisible i podaj identyfikator przycisku przesyłania formularza logowania. Przykład:

Web

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

Web

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

Używanie widżetu reCAPTCHA

Aby użyć widocznego widżetu reCAPTCHA, utwórz na stronie element zawierający widżet, a następnie utwórz obiekt RecaptchaVerifier, podając przy tym identyfikator kontenera. Na przykład:

Web

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {});

Web

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');

Opcjonalnie: określ parametry reCAPTCHA

Opcjonalnie możesz ustawić w obiekcie RecaptchaVerifier funkcje wywołania zwrotnego, które są wywoływane, gdy użytkownik rozwiąże zadanie reCAPTCHA lub reCAPTCHA wygaśnie, zanim użytkownik prześle formularz:

Web

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

Web

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

Opcjonalnie: wstępne renderowanie reCAPTCHA

Jeśli chcesz wstępnie wyrenderować reCAPTCHA przed przesłaniem żądania logowania, wywołaj render:

Web

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

Web

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

Po rozwiązaniu render otrzymasz identyfikator widżetu reCAPTCHA, którego możesz używać do wywoływania interfejsu API reCAPTCHA:

Web

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Wyślij kod weryfikacyjny na telefon użytkownika

Aby zainicjować logowanie się przy użyciu numeru telefonu, udostępnij użytkownikowi interfejs z prośbą o podanie numeru telefonu, a potem zadzwoń pod numer signInWithPhoneNumber, aby poprosić Firebase o wysłanie kodu uwierzytelniającego na telefon użytkownika SMS-em:

  1. Uzyskaj numer telefonu użytkownika.

    Wymagania prawne są różne, ale sprawdzona metoda i ustalenie oczekiwań użytkowników może spowodować otrzymanie przez nich SMS-a z prośbą o weryfikację. Obowiązują standardowe opłaty.

  2. Zadzwoń do użytkownika signInWithPhoneNumber, podając do niego numer telefonu użytkownika i utworzony wcześniej RecaptchaVerifier.

    Web

    import { getAuth, signInWithPhoneNumber } from "firebase/auth";
    
    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    
    const auth = getAuth();
    signInWithPhoneNumber(auth, phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });

    Web

    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });
    Jeśli signInWithPhoneNumber spowoduje błąd, zresetuj reCAPTCHA, aby użytkownik mógł spróbować ponownie:
    grecaptcha.reset(window.recaptchaWidgetId);
    
    // Or, if you haven't stored the widget ID:
    window.recaptchaVerifier.render().then(function(widgetId) {
      grecaptcha.reset(widgetId);
    });
    

Metoda signInWithPhoneNumber wysyła użytkownikowi test reCAPTCHA, a jeśli go zda, prosi o wysłanie przez Uwierzytelnianie Firebase na telefon użytkownika SMS-a z kodem weryfikacyjnym.

Logowanie użytkownika przy użyciu kodu weryfikacyjnego

Gdy połączenie z systemem signInWithPhoneNumber się powiedzie, poproś użytkownika o wpisanie kodu weryfikacyjnego otrzymanego SMS-em. Następnie zaloguj się jako użytkownik, przekazując kod do metody confirm obiektu ConfirmationResult, który został przekazany do modułu obsługi realizacji zamówienia signInWithPhoneNumber (czyli do jego bloku then). Przykład:

Web

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

Web

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

Jeśli wywołanie metody confirm się powiedzie, użytkownik jest zalogowany.

Pobieranie pośredniego obiektu AuthCredential

Jeśli musisz pobrać obiekt AuthCredential dla konta użytkownika, przekaż kod weryfikacyjny z wyniku potwierdzenia i kodu weryfikacyjnego do PhoneAuthProvider.credential, zamiast wywoływać confirm:

var credential = firebase.auth.PhoneAuthProvider.credential(confirmationResult.verificationId, code);

Następnie możesz zalogować się na koncie użytkownika za pomocą tych danych logowania:

firebase.auth().signInWithCredential(credential);

Testowanie na fikcyjnych numerach telefonów

Za pomocą konsoli Firebase możesz skonfigurować fikcyjne numery telefonów na potrzeby programowania. Testowanie za pomocą fikcyjnych numerów telefonu ma następujące korzyści:

  • Przetestuj uwierzytelnianie za pomocą numeru telefonu bez przekraczania limitu wykorzystania.
  • Przetestuj uwierzytelnianie numeru telefonu bez wysyłania SMS-a.
  • Przeprowadzaj kolejne testy z tym samym numerem telefonu bez ograniczania przepustowości. Pozwala to zminimalizować ryzyko odrzucenia aplikacji podczas procesu weryfikacji w App Store, jeśli osoba sprawdzająca użyje do testowania tego samego numeru telefonu.
  • Można je łatwo testować w środowiskach programistycznych bez dodatkowych nakładów pracy, takich jak możliwość tworzenia aplikacji w symulatorze iOS lub emulatorze Androida bez Usług Google Play.
  • Pisz testy integracji bez blokowania ich przez kontrole zabezpieczeń stosowane zwykle na prawdziwych numerach telefonów w środowisku produkcyjnym.

fikcyjne numery telefonów muszą spełniać te wymagania:

  1. Upewnij się, że podane numery telefonów są fikcyjne i nie istnieją. Uwierzytelnianie Firebase nie umożliwia ustawiania istniejących numerów telefonów, których używają rzeczywistych użytkowników, jako numerów testowych. Możesz na przykład użyć 555 numerów z prefiksem jako numerów testowych w USA, na przykład: +1 650-555-3434
  2. Numery telefonów muszą być poprawnie sformatowane pod kątem długości i innych ograniczeń. Będą one weryfikowane tak samo jak numer rzeczywistego użytkownika.
  3. Możesz dodać maksymalnie 10 numerów telefonów na potrzeby programowania.
  4. Używaj testowych numerów telefonów/kodów, które są trudne do odgadnięcia, i często je zmieniaj.

Tworzenie fikcyjnych numerów telefonów i kodów weryfikacyjnych

  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie.
  2. Na karcie Metoda logowania włącz operatora telefonicznego, jeśli jeszcze nie jest włączony.
  3. Otwórz menu Numery telefonów do testowania.
  4. Podaj numer telefonu, który chcesz przetestować, np. +1 650 555 3434.
  5. Podaj 6-cyfrowy kod weryfikacyjny dla tego numeru, np. 654321.
  6. Dodaj numer. W razie potrzeby możesz usunąć numer telefonu i jego kod, najeżdżając kursorem na odpowiedni wiersz i klikając ikonę kosza.

Testowanie ręczne

Możesz od razu rozpocząć korzystanie z fikcyjnego numeru telefonu w zgłoszeniu. Dzięki temu możesz przeprowadzać testy ręczne na etapach programowania, nie powodując problemów z limitami ani ograniczania przepustowości. Możesz też przeprowadzić test bezpośrednio za pomocą symulatora iOS lub emulatora Androida bez zainstalowanych Usług Google Play.

Gdy podasz fikcyjny numer telefonu i wyślesz kod weryfikacyjny, SMS nie zostanie wysłany. Zamiast tego, aby dokończyć logowanie, musisz podać wcześniej skonfigurowany kod weryfikacyjny.

Po zalogowaniu się zostaje utworzony użytkownik Firebase z tym numerem telefonu. Użytkownik zachowuje się tak samo i ma takie same właściwości jak prawdziwy użytkownik numeru telefonu oraz ma taki sam dostęp do Bazy danych czasu rzeczywistego, Cloud Firestore i innych usług. Token identyfikatora wytworzony podczas tego procesu ma taki sam podpis jak prawdziwy użytkownik numeru telefonu.

Jeśli chcesz dodatkowo ograniczyć dostęp, możesz ustawić dla tych użytkowników rolę testową za pomocą roszczeń niestandardowych, aby odróżnić ich jako fałszywych użytkowników.

Testowanie integracji

Oprócz testów ręcznych Uwierzytelnianie Firebase udostępnia interfejsy API, które pomagają pisać testy integracji na potrzeby testów uwierzytelniania przez telefon. Te interfejsy API wyłączają weryfikację aplikacji, wyłączając wymóg reCAPTCHA w przeglądarce i cichych powiadomieniach push w iOS. W ten sposób umożliwia to testowanie automatyzacji w ramach tych procesów i ułatwia wdrożenie. Poza tym umożliwiają testowanie natychmiastowej weryfikacji na Androidzie.

W przeglądarce ustaw appVerificationDisabledForTesting na true przed wyrenderowaniem firebase.auth.RecaptchaVerifier. Powoduje to automatyczne rozstrzygnięcie reCAPTCHA, dzięki czemu możesz przekazać numer telefonu bez konieczności rozwiązywania go ręcznie. Pamiętaj, że nawet jeśli reCAPTCHA jest wyłączony, użycie niefikcyjnego numeru telefonu i tak nie zadziała. W tym interfejsie API można używać tylko fikcyjnych numerów telefonów.

// Turn off phone auth app verification.
firebase.auth().settings.appVerificationDisabledForTesting = true;

var phoneNumber = "+16505554567";
var testVerificationCode = "123456";

// This will render a fake reCAPTCHA as appVerificationDisabledForTesting is true.
// This will resolve after rendering without app verification.
var appVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
// signInWithPhoneNumber will call appVerifier.verify() which will resolve with a fake
// reCAPTCHA response.
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
    .then(function (confirmationResult) {
      // confirmationResult can resolve with the fictional testVerificationCode above.
      return confirmationResult.confirm(testVerificationCode)
    }).catch(function (error) {
      // Error; SMS not sent
      // ...
    });

Widoczne i niewidoczne fałszywe weryfikatory aplikacji reCAPTCHA zachowują się inaczej, gdy weryfikacja aplikacji jest wyłączona:

  • Widoczna reCAPTCHA: gdy widoczna reCAPTCHA jest renderowana przez appVerifier.render(), automatycznie rozwiązuje się ona sama po ułamku sekundy. Jest to odpowiednik kliknięcia reCAPTCHA przez użytkownika natychmiast po wyrenderowaniu. Odpowiedź reCAPTCHA wygaśnie po pewnym czasie, a następnie zostanie ponownie automatycznie przeanalizowana.
  • Niewidoczna reCAPTCHA: niewidoczna reCAPTCHA nie rozpoznaje automatycznie podczas renderowania, tylko robi to podczas wywołania appVerifier.verify() lub gdy kotwica przycisku reCAPTCHA zostanie kliknięta po ułamku sekundy. Analogicznie odpowiedź wygasa po pewnym czasie i zostanie automatycznie rozpoznana dopiero po wywołaniu appVerifier.verify() lub po ponownym kliknięciu kotwicy przycisku reCAPTCHA.

Przy każdym rozwiązaniu przykładowej funkcji reCAPTCHA aktywna jest odpowiednia funkcja wywołania zwrotnego z fałszywą odpowiedzią. Jeśli określono też wywołanie zwrotne związane z wygaśnięciem, zostanie ono wywołane po wygaśnięciu.

Dalsze kroki

Gdy użytkownik zaloguje się po raz pierwszy, zostaje utworzone nowe konto użytkownika powiązane z danymi logowania (tj. nazwą użytkownika i hasłem, numerem telefonu lub informacjami o dostawcy uwierzytelniania), przy użyciu którego się zalogował. Nowe konto jest przechowywane w ramach projektu Firebase i może służyć do identyfikowania użytkowników we wszystkich aplikacjach w projekcie niezależnie od tego, jak się on zaloguje.

  • W aplikacjach zalecanym sposobem na sprawdzenie stanu uwierzytelniania użytkownika jest ustawienie obserwatora na obiekcie Auth. Podstawowe informacje o profilu użytkownika możesz pobrać z obiektu User. Zobacz Zarządzanie użytkownikami.

  • W Regułach zabezpieczeń Bazy danych czasu rzeczywistego Firebase i Cloud Storage możesz uzyskać unikalny identyfikator zalogowanego użytkownika ze zmiennej auth i za jego pomocą kontrolować, do jakich danych ma on dostęp.

Jeśli chcesz zezwolić użytkownikom na logowanie się w Twojej aplikacji za pomocą różnych dostawców uwierzytelniania, możesz połączyć dane logowania dostawcy uwierzytelniania z istniejącym kontem 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.
});