Uwierzytelniaj za pomocą Firebase za pomocą kont opartych na haśle w C++

Możesz użyć Firebase Authentication, aby umożliwić użytkownikom uwierzytelnianie w Firebase przy użyciu adresów e-mail i haseł oraz zarządzać kontami w aplikacji opartymi na hasłach.

Zanim zaczniesz

  1. Dodaj Firebase do projektu C++.
  2. Jeśli nie masz jeszcze połączenia aplikacji z projektem Firebase, zrób to w Firebase konsoli.
  3. Włącz logowanie się przy użyciu adresu e-mail i hasła:
    1. W Firebasekonsoli otwórz sekcję Uwierzytelnianie.
    2. Na karcie Metoda logowania włącz metodę logowania Adres e-mail/hasło i kliknij Zapisz.

Dostęp do zajęć firebase::auth::Auth

Klasa Auth jest bramą dla wszystkich wywołań interfejsu API.
  1. Dodaj pliki nagłówkowe Auth i App:
    #include "firebase/app.h"
    #include "firebase/auth.h"
  2. W kodzie inicjowania utwórz klasę firebase::App.
    #if defined(__ANDROID__)
      firebase::App* app =
          firebase::App::Create(firebase::AppOptions(), my_jni_env, my_activity);
    #else
      firebase::App* app = firebase::App::Create(firebase::AppOptions());
    #endif  // defined(__ANDROID__)
  3. Uzyskaj dostęp do zajęć firebase::auth::Auth dla firebase::App. Istnieje bezpośrednie powiązanie między AppAuth.
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);

Tworzenie konta z hasłem

Aby utworzyć nowe konto użytkownika z hasłem, wykonaj te czynności w kodzie logowania aplikacji:

  1. Gdy nowy użytkownik zarejestruje się za pomocą formularza rejestracji w Twojej aplikacji, wykonaj wszystkie wymagane przez nią czynności weryfikacyjne, np. sprawdź, czy hasło nowego konta zostało wpisane prawidłowo i czy spełnia wymagania dotyczące złożoności.
  2. Utwórz nowe konto, przekazując adres e-mail i hasło nowego użytkownika do Auth::CreateUserWithEmailAndPassword:
    firebase::Future<firebase::auth::AuthResult> result =
        auth->CreateUserWithEmailAndPassword(email, password);
  3. Jeśli program ma pętlę aktualizacji, która jest uruchamiana regularnie (np. 30 lub 60 razy na sekundę), możesz sprawdzać wyniki raz na aktualizację za pomocą funkcji Auth::CreateUserWithEmailAndPasswordLastResult:
    firebase::Future<firebase::auth::AuthResult> result =
        auth->CreateUserWithEmailAndPasswordLastResult();
    if (result.status() == firebase::kFutureStatusComplete) {
      if (result.error() == firebase::auth::kAuthErrorNone) {
        const firebase::auth::AuthResult auth_result = *result.result();
        printf("Create user succeeded for email %s\n",
               auth_result.user.email().c_str());
      } else {
        printf("Created user failed with error '%s'\n", result.error_message());
      }
    }
    Jeśli Twój program jest oparty na zdarzeniach, możesz też zarejestrować wywołanie zwrotne w obiekcie Future.

Logowanie użytkownika za pomocą adresu e-mail i hasła

Czynności związane z logowaniem użytkownika za pomocą hasła są podobne do czynności związanych z tworzeniem nowego konta. W funkcji logowania aplikacji wykonaj te czynności:

  1. Gdy użytkownik zaloguje się w Twojej aplikacji, przekaż jego adres e-mail i hasło do firebase::auth::Auth::SignInWithEmailAndPassword:
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInWithEmailAndPassword(email, password);
  2. Jeśli program ma pętlę aktualizacji, która jest uruchamiana regularnie (np. 30 lub 60 razy na sekundę), możesz sprawdzać wyniki raz na aktualizację za pomocą funkcji Auth::SignInWithEmailAndPasswordLastResult:
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInWithEmailAndPasswordLastResult();
    if (result.status() == firebase::kFutureStatusComplete) {
      if (result.error() == firebase::auth::kAuthErrorNone) {
        const firebase::auth::AuthResult auth_result = *result.result();
        printf("Sign in succeeded for email %s\n",
               auth_result.user.email().c_str());
      } else {
        printf("Sign in failed with error '%s'\n", result.error_message());
      }
    }
    Jeśli Twój program jest oparty na zdarzeniach, możesz też zarejestrować wywołanie zwrotne w obiekcie Future.

Rejestrowanie wywołania zwrotnego w przypadku obiektu Future

Niektóre programy mają Update funkcje, które są wywoływane 30 lub 60 razy na sekundę. Na przykład wiele gier korzysta z tego modelu. Te programy mogą wywoływać funkcje LastResult, aby sprawdzać połączenia asynchroniczne. Jeśli jednak program jest oparty na zdarzeniach, możesz zarejestrować funkcje wywołania zwrotnego. Po zakończeniu działania obiektu Future wywoływana jest funkcja wywołania zwrotnego.
void OnCreateCallback(const firebase::Future<firebase::auth::User*>& result,
                      void* user_data) {
  // The callback is called when the Future enters the `complete` state.
  assert(result.status() == firebase::kFutureStatusComplete);

  // Use `user_data` to pass-in program context, if you like.
  MyProgramContext* program_context = static_cast<MyProgramContext*>(user_data);

  // Important to handle both success and failure situations.
  if (result.error() == firebase::auth::kAuthErrorNone) {
    firebase::auth::User* user = *result.result();
    printf("Create user succeeded for email %s\n", user->email().c_str());

    // Perform other actions on User, if you like.
    firebase::auth::User::UserProfile profile;
    profile.display_name = program_context->display_name;
    user->UpdateUserProfile(profile);

  } else {
    printf("Created user failed with error '%s'\n", result.error_message());
  }
}

void CreateUser(firebase::auth::Auth* auth) {
  // Callbacks work the same for any firebase::Future.
  firebase::Future<firebase::auth::AuthResult> result =
      auth->CreateUserWithEmailAndPasswordLastResult();

  // `&my_program_context` is passed verbatim to OnCreateCallback().
  result.OnCompletion(OnCreateCallback, &my_program_context);
}
Jeśli wolisz, funkcja wywołania zwrotnego może być też lambdą.
void CreateUserUsingLambda(firebase::auth::Auth* auth) {
  // Callbacks work the same for any firebase::Future.
  firebase::Future<firebase::auth::AuthResult> result =
      auth->CreateUserWithEmailAndPasswordLastResult();

  // The lambda has the same signature as the callback function.
  result.OnCompletion(
      [](const firebase::Future<firebase::auth::User*>& result,
         void* user_data) {
        // `user_data` is the same as &my_program_context, below.
        // Note that we can't capture this value in the [] because std::function
        // is not supported by our minimum compiler spec (which is pre C++11).
        MyProgramContext* program_context =
            static_cast<MyProgramContext*>(user_data);

        // Process create user result...
        (void)program_context;
      },
      &my_program_context);
}

Zalecane: ustaw zasady dotyczące haseł

Możesz zwiększyć bezpieczeństwo kont, egzekwując wymogi w zakresie złożoności haseł.

Aby skonfigurować zasady dotyczące haseł w projekcie, otwórz kartę Zasady dotyczące haseł na stronie Ustawienia uwierzytelniania w konsoli Firebase:

Ustawienia uwierzytelniania

Zasady dotyczące haseł w usłudze Firebase Authentication obsługują te wymagania dotyczące haseł:

  • Wymagana mała litera

  • Wymagana jest wielka litera

  • Wymagany znak numeryczny

  • Wymagany znak niealfanumeryczny

    Wymaganie dotyczące znaków niealfanumerycznych spełniają te znaki:^ $ * . [ ] { } ( ) ? " ! @ # % & / \ , > < ' : ; | _ ~

  • Minimalna długość hasła (zakres od 6 do 30 znaków; domyślnie 6)

  • Maksymalna długość hasła (maksymalnie 4096 znaków)

Egzekwowanie zasad dotyczących haseł możesz włączyć w 2 trybach:

  • Wymagaj: próby rejestracji nie powiodą się, dopóki użytkownik nie zmieni hasła zgodnie z zasadami.

  • Powiadom: użytkownicy mogą zarejestrować się przy użyciu hasła, które nie spełnia wymogów. Gdy korzystasz z tego trybu, sprawdź po stronie klienta, czy hasło użytkownika jest zgodne z zasadami, i poproś użytkownika o zaktualizowanie hasła, jeśli nie jest ono zgodne z zasadami.

Nowi użytkownicy muszą zawsze wybrać hasło zgodne z Twoimi zasadami.

Jeśli masz aktywnych użytkowników, nie zalecamy włączania wymuszonej aktualizacji przy logowaniu, chyba że chcesz zablokować dostęp użytkownikom, których hasła nie są zgodne z Twoimi zasadami. Zamiast tego użyj trybu powiadamiania, który umożliwia użytkownikom logowanie się za pomocą bieżących haseł i informuje ich o wymaganiach, których nie spełnia ich hasło.

Zalecane: włącz ochronę przed wyliczaniem adresów e-mail

Niektóre metody Firebase Authentication, które przyjmują adresy e-mail jako parametry, zgłaszają konkretne błędy, jeśli adres e-mail jest niezarejestrowany, a powinien być zarejestrowany (np. podczas logowania się za pomocą adresu e-mail i hasła), lub zarejestrowany, a powinien być nieużywany (np. podczas zmiany adresu e-mail użytkownika). Może to być przydatne do sugerowania użytkownikom konkretnych rozwiązań, ale może też być wykorzystywane przez złośliwe podmioty do odkrywania adresów e-mail zarejestrowanych przez użytkowników.

Aby zmniejszyć to ryzyko, zalecamy włączenie ochrony przed wyliczaniem adresów e-mail w projekcie za pomocą narzędzia gcloud Google Cloud. Pamiętaj, że włączenie tej funkcji zmienia sposób raportowania błędów przez Firebase Authentication. Upewnij się, że Twoja aplikacja nie korzysta z bardziej szczegółowych błędów.

Dalsze kroki

Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i 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ł. Nowe konto jest przechowywane w projekcie 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 uzyskać 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 ma 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();