Uwierzytelniaj w Firebase przy użyciu numeru telefonu i języka C++

Możesz zalogować użytkownika za pomocą Firebase Authentication, wysyłając SMS-a na jego telefon. Użytkownik loguje się za pomocą jednorazowego kodu zawartego w SMS-ie.

Z tego dokumentu dowiesz się, jak wdrożyć proces logowania za pomocą numeru telefonu przy użyciu pakietu SDK Firebase.

Zanim zaczniesz

  1. Dodaj Firebase do projektu C++
  2. Jeśli nie masz jeszcze połączonej aplikacji z projektem w Firebase, zrób to w Firebase konsoli.
  3. Zapoznaj się z wymaganiami platformy dotyczącymi logowania za pomocą numeru telefonu:
    • Logowanie za pomocą numeru telefonu jest dostępne tylko na platformach mobilnych.
    • Na iOS logowanie za pomocą numeru telefonu wymaga urządzenia fizycznego i nie działa na symulatorze.

Potencjalne problemy z bezpieczeństwem

Uwierzytelnianie za pomocą samego numeru telefonu, choć wygodne, jest mniej bezpieczne niż inne dostępne metody, ponieważ numer telefonu można łatwo przekazać innemu użytkownikowi. Na urządzeniach z wieloma profilami użytkowników każdy użytkownik, który może odbierać SMS-y, może zalogować się na konto za pomocą numeru telefonu urządzenia.

Jeśli w aplikacji używasz logowania na podstawie numeru telefonu, powinieneś oferować je wraz z bezpieczniejszymi metodami logowania i informować użytkowników o kompromisach w zakresie bezpieczeństwa związanych z logowaniem za pomocą numeru telefonu.

Włączanie logowania za pomocą numeru telefonu w projekcie w Firebase

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

  1. W konsoli Firebase otwórz Bezpieczeństwo Uwierzytelnianie.
  2. Na karcie Metoda logowania włącz dostawcę logowania Telefon.
  3. Ustaw zasady dotyczące regionów, do których chcesz zezwolić na wysyłanie SMS-ów lub im tego zabronić. Ustawienie zasad dotyczących regionu SMS-ów może pomóc w ochronie aplikacji przed nadużyciami związanymi z SMS-ami. W przypadku nowych projektów domyślne zasady nie zezwalają na żadne regiony.
    1. W konsoli Firebase otwórz Zabezpieczenia > Uwierzytelnianie > karta Ustawienia.
    2. W sekcji Zasady dotyczące regionów SMS skonfiguruj zasady dotyczące regionów SMS.

Zacznij otrzymywać powiadomienia APNs (platformy Apple)

Aby korzystać z uwierzytelniania za pomocą numeru telefonu na platformach Apple, aplikacja musi mieć możliwość odbierania powiadomień APNs z Firebase. Gdy użytkownik loguje się za pomocą numeru telefonu po raz pierwszy na urządzeniu, Firebase Authentication wysyła na to urządzenie ciche powiadomienie push, aby sprawdzić, czy prośba o zalogowanie się za pomocą numeru telefonu pochodzi z Twojej aplikacji. (Z tego powodu logowanie za pomocą numeru telefonu nie może być używane na symulatorze).

Aby włączyć powiadomienia APNs do użytku z Firebase Authentication:

  1. W Xcode włącz powiadomienia push w projekcie.
  2. Prześlij certyfikat APNs do Firebase. Jeśli nie masz jeszcze certyfikatu APNs, utwórz go w Apple Developer Member Center.

    1. W konsoli Firebase otwórz Ustawienia > Ogólne. Następnie kliknij kartę Komunikacja w chmurze.
    2. Kliknij Prześlij certyfikat, aby przesłać certyfikat deweloperski, certyfikat produkcyjny lub oba te certyfikaty. Wymagane jest podanie co najmniej 1 wartości.
    3. W przypadku każdego certyfikatu wybierz plik .p12 i podaj hasło (jeśli jest wymagane). Upewnij się, że identyfikator pakietu tego certyfikatu jest zgodny z identyfikatorem pakietu aplikacji. Kliknij Zapisz.

Wysyłanie kodu weryfikacyjnego na telefon użytkownika

Aby rozpocząć logowanie za pomocą numeru telefonu, wyświetl użytkownikowi interfejs z prośbą o podanie numeru telefonu, a następnie wywołaj funkcję PhoneAuthProvider::VerifyPhoneNumber, aby poprosić Firebase o wysłanie kodu uwierzytelniającego na telefon użytkownika w SMS-ie:

  1. Uzyskaj numer telefonu użytkownika.

    Wymagania prawne są różne, ale zgodnie ze sprawdzonymi metodami i aby spełnić oczekiwania użytkowników, należy poinformować ich, że jeśli używają logowania przez telefon, mogą otrzymać SMS-a z prośbą o weryfikację, a w takim przypadku obowiązują standardowe stawki.

  2. Wywołaj funkcję PhoneAuthProvider::VerifyPhoneNumber, przekazując do niej numer telefonu użytkownika.
    class PhoneListener : public PhoneAuthProvider::Listener {
     public:
      ~PhoneListener() override {}
    
      void OnVerificationCompleted(PhoneAuthCredential credential) override {
        // Auto-sms-retrieval or instant validation has succeeded (Android only).
        // No need for the user to input the verification code manually.
        // `credential` can be used instead of calling GetCredential().
      }
    
      void OnVerificationFailed(const std::string& error) override {
        // Verification code not sent.
      }
    
      void OnCodeSent(const std::string& verification_id,
                      const PhoneAuthProvider::ForceResendingToken&
                          force_resending_token) override {
        // Verification code successfully sent via SMS.
        // Show the Screen to enter the Code.
        // Developer may want to save that verification_id along with other app states in case
        // the app is terminated before the user gets the SMS verification code.
      }
    };
    
    PhoneListener phone_listener;
    PhoneAuhtOptions options;
    options.timeout_milliseconds = kAutoVerifyTimeOut;
    options.phone_number = phone_number;
    PhoneAuthProvider& phone_provider = PhoneAuthProvider::GetInstance(auth);
    phone_provider->VerifyPhoneNumber(options, &phone_listener);
    Gdy wywołasz PhoneAuthProvider::VerifyPhoneNumber, Firebase,
    • (na iOS) wysyła do aplikacji ciche powiadomienie push,
    • wysyła SMS-a z kodem uwierzytelniania na podany numer telefonu i przekazuje identyfikator weryfikacji do funkcji zakończenia. Aby zalogować użytkownika, potrzebujesz zarówno kodu weryfikacyjnego, jak i identyfikatora weryfikacji.
  3. Zapisz identyfikator weryfikacji i przywróć go po wczytaniu aplikacji. Dzięki temu możesz mieć pewność, że nadal masz prawidłowy identyfikator weryfikacji, jeśli aplikacja zostanie zamknięta, zanim użytkownik dokończy proces logowania (np. podczas przełączania się na aplikację do SMS-ów).

    Identyfikator weryfikacji możesz przechowywać w dowolny sposób. Jeśli piszesz za pomocą frameworka C++ na wielu platformach, powinien on zapewniać powiadomienia o zakończeniu i przywróceniu działania aplikacji. W przypadku tych zdarzeń możesz odpowiednio zapisać i przywrócić identyfikator weryfikacji.

Jeśli połączenie z VerifyPhoneNumber spowoduje wywołanie OnCodeSent na urządzeniu nasłuchującym, możesz poprosić użytkownika o wpisanie kodu weryfikacyjnego, gdy otrzyma go w SMS-ie.

Z drugiej strony, jeśli wywołanie funkcji VerifyPhoneNumber zwróci wartość OnVerificationCompleted, oznacza to, że weryfikacja automatyczna się powiodła i masz teraz wartość PhoneAuthCredential, której możesz używać w sposób opisany poniżej.

Logowanie użytkownika za pomocą kodu weryfikacyjnego

Gdy użytkownik poda aplikacji kod weryfikacyjny z SMS-a, zaloguj go, tworząc obiekt PhoneAuthCredential na podstawie kodu weryfikacyjnego i identyfikatora weryfikacji, a następnie przekaż ten obiekt do funkcji Auth::SignInWithCredential.

  1. Poproś użytkownika o kod weryfikacyjny.
  2. Utwórz obiekt Credential na podstawie kodu weryfikacyjnego i identyfikatora weryfikacji.
    PhoneAuthCredential credential = phone_auth_provider->GetCredential(
        verification_id_.c_str(), verification_code.c_str());
        
  3. Zaloguj użytkownika za pomocą obiektu Credential:
    Future<User> future = auth_->SignInWithCredential(credential);
    future.OnCompletion(
        [](const Future<User*>& result, void*) {
          if (result.error() == kAuthErrorNone) {
            // Successful.
            // User is signed in.
            User user = *result.result();
    
            // This should display the phone number.
            printf("Phone number: %s", user.phone_number().c_str());
    
            // The phone number provider UID is the phone number itself.
            printf("Phone provider uid: %s", user.uid().c_str());
    
            // The phone number providerID is 'phone'
            printf("Phone provider ID: %s", user.provider_id().c_str());
          } else {
            // Error.
            printf("Sign in error: %s", result.error_message().c_str());
          }
        },
        nullptr);

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 firebase::auth::User:

    firebase::auth::User user = auth->current_user();
    if (user.is_valid()) {
      std::string name = user.display_name();
      std::string email = user.email();
      std::string photo_url = user.photo_url();
      // The user's ID, unique to the Firebase project.
      // Do NOT use this value to authenticate with your backend server,
      // if you have one. Use firebase::auth::User::Token() instead.
      std::string uid = user.uid();
    }
  • 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():

auth->SignOut();