Firebase 인증을 사용해서 사용자가 이메일 계정과 비밀번호로 Firebase 인증을 처리할 수 있도록 하고, 앱의 비밀번호 기반 계정을 관리할 수도 있습니다.
시작하기 전에
- C++ 프로젝트에 Firebase를 추가합니다.
- 아직 Firebase 프로젝트에 앱을 연결하지 않았다면 Firebase Console에서 연결합니다.
- 다음과 같이 이메일 및 비밀번호 로그인을 사용 설정합니다.
- Firebase Console에서 인증 섹션을 엽니다.
- 로그인 방법 탭에서 이메일/비밀번호 로그인 방법을 사용 설정하고 저장을 클릭합니다.
firebase::auth::Auth
클래스 액세스
Auth
클래스는 모든 API 호출에 대한 게이트웨이입니다.
- Auth 및 App 헤더 파일을 추가합니다.
#include "firebase/app.h" #include "firebase/auth.h"
- 초기화 코드에서
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__)
firebase::App
의firebase::auth::Auth
클래스를 획득합니다.App
과Auth
는 일대일 매핑 관계입니다.firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
비밀번호 기반 계정 생성하기
비밀번호가 있는 신규 사용자 계정을 생성하려면 앱의 로그인 코드에서 다음 절차를 완료합니다.
- 신규 사용자가 앱의 가입 양식을 사용해 가입하고 나면 필요에 따라 앱에서 계정 유효성 검사 절차를 완료합니다. 검사 항목의 예로는 신규 계정의 비밀번호를 정확하게 입력했는지, 비밀번호가 복잡성 조건을 충족하는지 등이 있습니다.
- 다음과 같이 신규 사용자의 이메일 주소와 비밀번호를
Auth::CreateUserWithEmailAndPassword
에 전달하여 신규 계정을 생성합니다.firebase::Future<firebase::auth::AuthResult> result = auth->CreateUserWithEmailAndPassword(email, password);
- 프로그램에 정기적으로 실행되는 업데이트 루프(예: 초당 30회 또는 60회)가 있는 경우 다음과 같이
Auth::CreateUserWithEmailAndPasswordLastResult
를 사용해 업데이트 시마다 한 번씩 결과를 확인할 수 있습니다. 또는 프로그램이 이벤트 기반이라면 Future에 콜백을 등록하는 것이 나을 수도 있습니다.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()); } }
이메일 주소와 비밀번호로 사용자 로그인 처리
비밀번호로 사용자 로그인을 처리하는 절차는 신규 계정을 생성하는 절차와 비슷합니다. 앱의 로그인 함수에서 다음 절차를 따르세요.
- 사용자가 앱에 로그인하면, 다음과 같이 사용자의 이메일 주소와 비밀번호를
firebase::auth::Auth::SignInWithEmailAndPassword
에 전달합니다.firebase::Future<firebase::auth::AuthResult> result = auth->SignInWithEmailAndPassword(email, password);
- 프로그램에 정기적으로 실행되는 업데이트 루프(예: 초당 30회 또는 60회)가 있는 경우 다음과 같이
Auth::SignInWithEmailAndPasswordLastResult
를 사용해 업데이트 시마다 한 번씩 결과를 확인할 수 있습니다. 또는 프로그램이 이벤트 기반이라면 Future에 콜백을 등록하는 것이 나을 수도 있습니다.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에 콜백 등록하기
일부 프로그램에는 초당 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); }
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 인증 메서드에서 특정 오류가 발생합니다. 이는 사용자에게 특정 조치를 제안하는 데 유용할 수 있지만 사용자가 등록한 이메일 주소를 악의적인 행위자가 발견하는 데 악용될 수도 있습니다.
이러한 위험을 완화하려면 Google Cloud gcloud
도구를 사용하여 프로젝트에 이메일 열거 보호 기능을 사용 설정하는 것이 좋습니다. 이 기능을 사용 설정하면 Firebase 인증의 오류 보고 동작이 변경됩니다. 앱이 더 구체적인 오류에 의존하지 않는지 확인하세요.
다음 단계
사용자가 처음으로 로그인하면 신규 사용자 계정이 생성되고 사용자가 로그인할 때 사용한 사용자 인증 정보(사용자 이름과 비밀번호, 전화번호 또는 인증 제공업체 정보)에 연결됩니다. 이 신규 계정은 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 실시간 데이터베이스와 Cloud Storage 보안 규칙의
auth
변수에서 로그인한 사용자의 고유 사용자 ID를 가져온 후 이 ID를 통해 사용자가 액세스할 수 있는 데이터를 관리할 수 있습니다.
인증 제공업체의 사용자 인증 정보를 기존 사용자 계정에 연결하면 사용자가 여러 인증 제공업체를 통해 앱에 로그인할 수 있습니다.
사용자를 로그아웃시키려면 SignOut()
을 호출합니다.
auth->SignOut();