Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

使用 GitHub 和 C++ 進行身份驗證

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

您可以通過將 GitHub 身份驗證集成到您的應用中,讓您的用戶使用他們的 GitHub 帳戶向 Firebase 進行身份驗證。

在你開始之前

  1. 將 Firebase 添加到您的 C++ 項目中。
  2. Firebase 控制台中,打開Auth部分。
  3. 登錄方法選項卡上,啟用GitHub提供程序。
  4. 將該提供者的開發者控制台中的客戶端 ID客戶端密碼添加到提供者配置中:
    1. 在 GitHub 上將您的應用程序註冊為開發人員應用程序,並獲取您的應用程序的 OAuth 2.0客戶端 ID客戶端密鑰
    2. 確保您的 Firebase OAuth 重定向 URI (例如my-app-12345.firebaseapp.com/__/auth/handler )在GitHub 應用程序的 config的應用程序設置頁面中設置為您的授權回調 URL
  5. 單擊保存

訪問firebase::auth::Auth

Auth類是所有 API 調用的網關。
  1. 添加 Auth 和 App 頭文件:
    #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::App獲取firebase::auth::Auth類。 AppAuth之間存在一對一的映射關係。
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
    

使用 Firebase 進行身份驗證

  1. 按照AndroidiOS+的說明獲取已登錄 GitHub 用戶的令牌。
  2. 用戶成功登錄後,將令牌交換為 Firebase 憑據,並使用 Firebase 憑據向 Firebase 進行身份驗證:
    firebase::auth::Credential credential =
        firebase::auth::GitHubAuthProvider::GetCredential(token);
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithCredential(credential);
    
  3. 如果您的程序有一個定期運行的更新循環(例如每秒 30 或 60 次),您可以使用Auth::SignInWithCredentialLastResult每次更新檢查一次結果:
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithCredentialLastResult();
    if (result.status() == firebase::kFutureStatusComplete) {
      if (result.error() == firebase::auth::kAuthErrorNone) {
        firebase::auth::User* user = *result.result();
        printf("Sign in succeeded for `%s`\n", user->display_name().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::User*> 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::User*> 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 項目的一部分存儲,可用於在項目中的每個應用中識別用戶,無論用戶如何登錄。

  • 在您的應用程序中,您可以從firebase::auth::User對象獲取用戶的基本個人資料信息:

    firebase::auth::User* user = auth->current_user();
    if (user != nullptr) {
      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 實時數據庫和雲存儲安全規則中,您可以從auth變量中獲取登錄用戶的唯一用戶 ID,並使用它來控制用戶可以訪問哪些數據。

您可以通過將身份驗證提供程序憑據鏈接到現有用戶帳戶來允許用戶使用多個身份驗證提供程序登錄您的應用程序。

要註銷用戶,請調用SignOut()

auth->SignOut();