使用 C++ 以密碼式帳戶向 Firebase 驗證

您可以使用 Firebase Authentication 讓使用者透過 Firebase 使用自己的電子郵件地址和密碼,管理應用程式的 使用 API

事前準備

  1. 將 Firebase 新增至您的 C++ 專案
  2. 如果您尚未將應用程式連結至 Firebase 專案,請前往 Firebase 控制台
  3. 啟用電子郵件/密碼登入功能:
    1. Firebase 控制台中開啟 找到「Auth」專區。
    2. 在「Sign in method」分頁中啟用「Email/password」登入 方法並點選「儲存」

存取 firebase::auth::Auth 類別

Auth 類別是所有 API 呼叫的閘道,
  1. 新增驗證與應用程式標頭檔案:
    #include "firebase/app.h"
    #include "firebase/auth.h"
    
  2. 在初始化程式碼中,建立 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. 取得 firebase::Appfirebase::auth::Auth 類別。 AppAuth 之間有一對一的對應關係。
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
    

建立以密碼為基礎的帳戶

如要以密碼建立新的使用者帳戶,請完成下列步驟: 應用程式的登入碼:

  1. 當新使用者透過應用程式的註冊表單註冊時,請完成新的使用者 帳戶驗證步驟,例如驗證 已正確輸入新帳戶的密碼,符合您的複雜程度 Google Cloud 就是最佳選擇
  2. 傳送新使用者的電子郵件地址和密碼,建立新帳戶 至 Auth::CreateUserWithEmailAndPassword
    firebase::Future<firebase::auth::AuthResult> result =
        auth->CreateUserWithEmailAndPassword(email, password);
    
  3. 如果您的程式有定期執行的更新迴圈 (例如 30 或 60) 每秒可執行 1 次 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());
      }
    }
    
    或者,如果您的計畫是依據事件推動,建議您 在 Future (未來)。
,瞭解如何調查及移除這項存取權。

透過電子郵件地址和密碼登入使用者帳戶

使用密碼登入使用者的步驟與 建立新帳戶。在應用程式的登入函式中執行以下操作:

  1. 使用者登入應用程式時,傳送使用者的電子郵件地址並 firebase::auth::Auth::SignInWithEmailAndPassword 的密碼:
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInWithEmailAndPassword(email, password);
    
  2. 如果您的程式有定期執行的更新迴圈 (例如 30 或 60) 每秒可執行 1 次 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());
      }
    }
    
    或者,如果您的計畫是依據事件推動,建議您 在 Future (未來)。

在 Future 上註冊回呼

某些程式包含可呼叫每秒 30 或 60 次的 Update 函式。 舉例來說,許多遊戲都採用這個模型。這些程式可以呼叫 LastResult 函式來輪詢非同步呼叫。 不過,如果您的程式是以事件驅動,建議您註冊回呼函式。 Future 完成後,會呼叫回呼函式。
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);
}
如有需要,回呼函式也可以是 lambda。
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);
}

建議:啟用電子郵件列舉防護功能

部分 Firebase Authentication 方法會將電子郵件地址做為參數擲回 特定錯誤 (在必須註冊該電子郵件地址時取消註冊) (例如,使用電子郵件地址和密碼登入時) ,哪些情況不能使用 (例如變更使用者的電子郵件地址)。 雖然這麼做有助於向使用者建議具體的解決方法, 以免不肖人士濫用,以找出您註冊的電子郵件地址 使用者。

為降低這個風險,建議您啟用電子郵件列舉防護功能 為專案使用 Google Cloud gcloud 工具請注意,啟用這個 功能會變更 Firebase Authentication 的錯誤回報行為,請確認您的應用程式 而不是仰賴更具體的錯誤

後續步驟

使用者首次登入後,系統會建立新的使用者帳戶 也就是使用者的名稱和密碼 號碼或驗證提供者資訊,也就是使用者登入時使用的網址。這項新功能 帳戶儲存為 Firebase 專案的一部分,可用來識別 即可限制使用者登入專案中的所有應用程式

  • 在您的應用程式中,您可以透過 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();
    }
    
  • 在你的Firebase Realtime DatabaseCloud Storage中 查看安全性規則 透過 auth 變數取得已登入使用者的不重複使用者 ID。 控管使用者可以存取的資料

您可以讓使用者透過多重驗證機制登入您的應用程式 將驗證供應商憑證連結至 現有的使用者帳戶

如要登出使用者,請呼叫 SignOut()

auth->SignOut();