Uwierzytelnij się w Firebase za pomocą numeru telefonu za pomocą JavaScript

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

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

Najłatwiejszym sposobem dodania logowania za pomocą numeru telefonu do aplikacji jest użycie FirebaseUI , który obejmuje widżet logowania typu drop-in, który implementuje przepływy logowania dla logowania za pomocą numeru telefonu, a także logowanie oparte na hasłach i sfederowane -w. W tym dokumencie opisano, jak zaimplementować proces logowania za pomocą numeru telefonu przy użyciu pakietu Firebase SDK.

Zanim zaczniesz

Jeśli jeszcze tego nie zrobiłeś, skopiuj fragment inicjujący z konsoli Firebase do swojego projektu zgodnie z opisem w sekcji Dodawanie Firebase do projektu JavaScript .

Obawy dotyczące bezpieczeństwa

Uwierzytelnianie przy użyciu samego numeru telefonu, choć wygodne, jest mniej bezpieczne niż inne dostępne metody, ponieważ posiadanie numeru telefonu można łatwo przenosić między użytkownikami. Ponadto na urządzeniach z wieloma profilami użytkowników każdy użytkownik, który może odbierać wiadomości SMS, może zalogować się na konto przy użyciu numeru telefonu urządzenia.

Jeśli korzystasz z logowania na podstawie numeru telefonu w swojej aplikacji, powinieneś oferować go wraz z bezpieczniejszymi metodami logowania i informować użytkowników o kompromisach związanych z bezpieczeństwem korzystania z logowania za pomocą numeru telefonu.

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

Aby logować użytkowników przez SMS, musisz najpierw włączyć metodę logowania za pomocą numeru telefonu dla swojego projektu Firebase:

  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie .
  2. Na stronie Metoda logowania włącz metodę logowania za pomocą numeru telefonu .
  3. Na tej samej stronie, jeśli domena, w której będzie hostowana Twoja aplikacja, nie jest wymieniona w sekcji Domeny przekierowania OAuth , dodaj swoją domenę.

Limit żądań logowania za pomocą numeru telefonu Firebase jest na tyle wysoki, że nie ma to wpływu na większość aplikacji. Jeśli jednak musisz zalogować bardzo dużą liczbę użytkowników za pomocą uwierzytelniania telefonicznego, może być konieczne uaktualnienie planu cenowego. Zobacz cennik .

Skonfiguruj weryfikator reCAPTCHA

Zanim będziesz mógł logować użytkowników przy użyciu ich numerów telefonów, musisz skonfigurować weryfikator reCAPTCHA Firebase. Firebase używa reCAPTCHA, by zapobiegać nadużyciom, na przykład zapewniając, że prośba o weryfikację numeru telefonu pochodzi z jednej z domen dozwolonych w Twojej aplikacji.

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

Obiekt RecaptchaVerifier obsługuje niewidoczny reCAPTCHA , który często może zweryfikować użytkownika bez konieczności wykonywania jakichkolwiek działań przez użytkownika, a także widżet reCAPTCHA, który zawsze wymaga interakcji użytkownika do pomyślnego zakończenia.

Bazowe renderowane reCAPTCHA można zlokalizować zgodnie z preferencjami użytkownika, aktualizując kod języka w instancji Auth przed renderowaniem reCAPTCHA. Wspomniana lokalizacja będzie dotyczyła również wysłanej do użytkownika wiadomości SMS zawierającej kod weryfikacyjny.

Web version 9

import { getAuth } from "firebase/auth";

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

Web version 8

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

Użyj niewidocznego reCAPTCHA

Aby użyć niewidocznego reCAPTCHA, utwórz obiekt RecaptchaVerifier z parametrem size ustawionym na invisible , określając identyfikator przycisku, który przesyła formularz logowania. Na przykład:

Web version 9

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

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

Web version 8

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

Użyj widżetu reCAPTCHA

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

Web version 9

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

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

Web version 8

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

Opcjonalnie: Określ parametry reCAPTCHA

Możesz opcjonalnie ustawić funkcje wywołania zwrotnego w obiekcie RecaptchaVerifier , które są wywoływane, gdy użytkownik rozwiąże reCAPTCHA lub reCAPTCHA wygaśnie przed przesłaniem formularza:

Web version 9

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

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

Web version 8

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: wyrenderuj wstępnie reCAPTCHA

Jeśli chcesz wstępnie wyrenderować reCAPTCHA przed przesłaniem prośby o zalogowanie, wywołaj render :

Web version 9

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

Web version 8

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

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

Web version 9

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web version 8

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Wyślij kod weryfikacyjny na telefon użytkownika

Aby zainicjować logowanie za pomocą numeru telefonu, zaprezentuj użytkownikowi interfejs proszący o podanie numeru telefonu, a następnie zadzwoń do 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 najlepszym rozwiązaniem i określeniem oczekiwań wobec użytkowników jest poinformowanie ich, że jeśli korzystają z logowania przez telefon, mogą otrzymać wiadomość SMS w celu weryfikacji i obowiązują standardowe stawki.

  2. Call signInWithPhoneNumber , przekazując do niego numer telefonu użytkownika oraz utworzony wcześniej RecaptchaVerifier .

    Web version 9

    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 version 8

    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 użytkownikowi wyzwanie reCAPTCHA, a jeśli użytkownik go pomyślnie, żąda, aby usługa Uwierzytelnianie Firebase wysłała na telefon użytkownika wiadomość SMS zawierającą kod weryfikacyjny.

Zaloguj się użytkownika za pomocą kodu weryfikacyjnego

Po pomyślnym wywołaniu signInWithPhoneNumber użytkownika o wpisanie kodu weryfikacyjnego otrzymanego SMS-em. Następnie zaloguj się użytkownika, przekazując kod do metody signInWithPhoneNumber obiektu ConfirmationResult , który został przekazany do programu obsługi realizacji confirm ( then jego bloku). Na przykład:

Web version 9

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 version 8

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 confirm powiodło się, użytkownik jest pomyślnie zalogowany.

Uzyskaj pośredni obiekt AuthCredential

Jeśli chcesz uzyskać obiekt AuthCredential dla konta użytkownika, przekaż kod weryfikacyjny z wyniku potwierdzenia i kod weryfikacyjny do PhoneAuthProvider.credential zamiast dzwonić do confirm :

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

Następnie możesz zalogować użytkownika za pomocą poświadczenia:

firebase.auth().signInWithCredential(credential);

Testuj z fikcyjnymi numerami telefonów

Za pomocą konsoli Firebase możesz skonfigurować fikcyjne numery telefonów do programowania. Testowanie z fikcyjnymi numerami telefonów zapewnia następujące korzyści:

  • Przetestuj uwierzytelnianie numeru telefonu bez zużywania limitu użycia.
  • Przetestuj uwierzytelnianie numeru telefonu bez wysyłania wiadomości SMS.
  • Przeprowadzaj kolejne testy z tym samym numerem telefonu bez dławienia. Minimalizuje to ryzyko odrzucenia podczas procesu recenzji App Store, jeśli recenzent użyje tego samego numeru telefonu do testów.
  • Łatwe testowanie w środowiskach programistycznych bez dodatkowego wysiłku, na przykład możliwość programowania w symulatorze systemu iOS lub emulatorze systemu Android bez usług Google Play.
  • Twórz testy integracyjne bez blokowania przez kontrole bezpieczeństwa stosowane zwykle w przypadku prawdziwych numerów telefonów w środowisku produkcyjnym.

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

  1. Upewnij się, że używasz numerów telefonów, które są rzeczywiście fikcyjne i jeszcze nie istnieją. Uwierzytelnianie Firebase nie pozwala na ustawienie istniejących numerów telefonów używanych przez prawdziwych użytkowników jako numerów testowych. Jedną z opcji jest użycie 555 numerów z prefiksem jako testowych numerów telefonów 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ą nadal przechodzić tę samą weryfikację, co numer telefonu prawdziwego użytkownika.
  3. Możesz dodać maksymalnie 10 numerów telefonów do rozwoju.
  4. Używaj testowych numerów/kodów telefonów, które są trudne do odgadnięcia i często je zmieniaj.

Twórz fikcyjne numery telefonów i kody weryfikacyjne

  1. W konsoli Firebase otwórz sekcję Uwierzytelnianie .
  2. Na karcie Metoda logowania włącz dostawcę usług telefonicznych, jeśli jeszcze tego nie zrobiłeś.
  3. Otwórz menu Numery telefonów do testowania akordeonu.
  4. Podaj numer telefonu, który chcesz przetestować, na przykład: +1 650-555-3434 .
  5. Podaj 6-cyfrowy kod weryfikacyjny dla tego konkretnego numeru, na przykład: 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 bezpośrednio zacząć używać fikcyjnego numeru telefonu w swojej aplikacji. Pozwala to na ręczne testowanie na etapach rozwoju bez problemów z przydziałem lub ograniczaniem przepustowości. Możesz także testować bezpośrednio z symulatora iOS lub emulatora Androida bez zainstalowanych usług Google Play.

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

Po zakończeniu logowania zostanie utworzony użytkownik Firebase z tym numerem telefonu. Użytkownik zachowuje się tak samo i ma takie same właściwości jak użytkownik z prawdziwym numerem telefonu i może w ten sam sposób uzyskiwać dostęp do Bazy danych czasu rzeczywistego/Cloud Firestore i innych usług. Token ID wybity podczas tego procesu ma taki sam podpis jak użytkownik z prawdziwym numerem telefonu.

Inną opcją jest ustawienie roli testowej za pomocą oświadczeń niestandardowych dla tych użytkowników, aby odróżnić ich jako fałszywych użytkowników, jeśli chcesz dodatkowo ograniczyć dostęp.

Testy integracyjne

Oprócz testów ręcznych Uwierzytelnianie Firebase udostępnia interfejsy API ułatwiające pisanie testów integracji na potrzeby testowania uwierzytelniania telefonicznego. Te interfejsy API wyłączają weryfikację aplikacji, wyłączając wymaganie reCAPTCHA w Internecie i ciche powiadomienia push w iOS. Umożliwia to testowanie automatyzacji w tych przepływach i łatwiejsze do wdrożenia. Ponadto zapewniają możliwość testowania przepływów natychmiastowej weryfikacji w systemie Android.

W internecie ustaw appVerificationDisabledForTesting na true przed renderowaniem firebase.auth.RecaptchaVerifier . To automatycznie rozwiązuje reCAPTCHA, umożliwiając przekazanie numeru telefonu bez ręcznego rozwiązywania go. Pamiętaj, że nawet jeśli funkcja reCAPTCHA jest wyłączona, użycie niefikcyjnego numeru telefonu nadal nie zakończy się logowaniem. 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 makiety weryfikatorów aplikacji reCAPTCHA zachowują się inaczej, gdy weryfikacja aplikacji jest wyłączona:

  • Widoczny reCAPTCHA : Gdy widoczny reCAPTCHA jest renderowany przez appVerifier.render() , automatycznie rozwiązuje się po ułamku sekundy opóźnienia. Odpowiada to kliknięciu przez użytkownika reCAPTCHA natychmiast po renderowaniu. Odpowiedź reCAPTCHA wygaśnie po pewnym czasie, a następnie zostanie automatycznie rozwiązana.
  • Invisible reCAPTCHA : niewidoczny reCAPTCHA nie jest automatycznie rozwiązywany podczas renderowania, a zamiast tego robi to po appVerifier.verify() lub po kliknięciu zakotwiczenia przycisku reCAPTCHA po ułamku sekundy opóźnienia. Podobnie odpowiedź wygaśnie po pewnym czasie i zostanie automatycznie rozwiązana dopiero po appVerifier.verify() lub po ponownym kliknięciu zakotwiczenia przycisku reCAPTCHA.

Za każdym razem, gdy próba reCAPTCHA zostanie rozwiązana, odpowiednia funkcja wywołania zwrotnego zostanie wywołana zgodnie z oczekiwaniami z fałszywą odpowiedzią. Jeśli określono również wywołanie zwrotne wygaśnięcia, zostanie ono wywołane po wygaśnięciu.

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 — przy użyciu 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 aplikacjach zalecanym sposobem poznania stanu uwierzytelniania użytkownika jest ustawienie obserwatora na obiekcie Auth . Następnie można uzyskać podstawowe informacje o profilu użytkownika z obiektu User . 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 ma 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, zadzwoń do signOut :

Web version 9

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

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

Web version 8

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});