Google은 흑인 공동체를 위한 인종적 평등을 추구하기 위해 노력하고 있습니다. 자세히 알아보기

C++로 Google Play 게임 서비스를 사용하여 인증

Google Play 게임 서비스를 사용하여 Firebase를 기반으로 하고 C++로 작성된 Android 게임에 플레이어를 로그인할 수 있습니다. Firebase로 Google Play 게임 서비스 로그인을 사용하려면 먼저 Google Play 게임으로 플레이어에 로그인하고 로그인할 때 OAuth 2.0 인증 코드를 요청하세요. 그런 다음 인증 코드를 PlayGamesAuthProvider 에 전달하여 Firebase에 인증하는 데 사용할 수 있는 Firebase 자격 증명을 생성합니다.

시작하기 전에

Firebase 인증 을 사용하려면 먼저 다음을 수행해야 합니다.

  • C++ 프로젝트를 등록하고 Firebase를 사용하도록 구성합니다.

    C++ 프로젝트에서 이미 Firebase를 사용하고 있다면 Firebase에 이미 등록 및 구성되어 있는 것입니다.

  • Firebase C++ SDK 를 C++ 프로젝트에 추가합니다.

C++ 프로젝트에 Firebase를 추가하려면 Firebase 콘솔 과 공개 C++ 프로젝트 모두에서 작업을 수행해야 합니다(예: 콘솔에서 Firebase 구성 파일을 다운로드한 다음 C++ 프로젝트로 이동).

Firebase 프로젝트 설정

  1. 아직 설정하지 않았다면 Firebase 콘솔의 설정 페이지에서 게임의 SHA-1 지문을 설정합니다.

    signingReport 명령을 사용하여 서명 인증서의 SHA 해시를 가져올 수 있습니다.

    ./gradlew signingReport

  2. Google Play 게임을 로그인 공급자로 활성화:

    1. 프로젝트의 웹 서버 클라이언트 ID와 클라이언트 암호를 찾으십시오. 웹 서버 클라이언트 ID는 Firebase 프로젝트를 Google Play 인증 서버에 식별합니다.

      이러한 값을 찾으려면:

      1. Google API 콘솔 자격 증명 페이지에서 Firebase 프로젝트를 엽니다.
      2. OAuth 2.0 클라이언트 ID 섹션에서 웹 클라이언트(Google 서비스에서 자동 생성) 세부정보 페이지를 엽니다. 이 페이지는 웹 서버 클라이언트 ID와 비밀을 나열합니다.
    2. 그런 다음 Firebase 콘솔 에서 인증 섹션을 엽니다.

    3. 로그인 방법 탭에서 Play 게임 로그인 공급자를 활성화합니다. API 콘솔에서 가져온 프로젝트의 웹 서버 클라이언트 ID와 클라이언트 암호를 지정해야 합니다.

Firebase 앱 정보로 Play 게임 서비스 구성

  1. Google Play Console 에서 Google Play 앱을 열거나 새로 만듭니다.

  2. 성장 섹션에서 Play 게임 서비스 > 설정 및 관리 > 구성 을 클릭합니다.

  3. 예, 내 게임은 이미 Google API 를 사용합니다를 클릭하고 목록에서 Firebase 프로젝트를 선택한 다음 사용 을 클릭합니다.

  4. Play 게임 서비스 구성 페이지에서 자격 증명 추가 를 클릭합니다.

    1. 게임 서버 유형을 선택합니다.
    2. OAuth 클라이언트 필드에서 프로젝트의 웹 클라이언트 ID를 선택합니다. Play 게임 로그인을 활성화할 때 지정한 클라이언트 ID와 동일한지 확인하세요.
    3. 변경 사항을 저장합니다.
  5. 계속해서 Play 게임 서비스 구성 페이지에서 자격 증명 추가 를 다시 클릭합니다.

    1. Android 유형을 선택합니다.
    2. OAuth 클라이언트 필드에서 프로젝트의 Android 클라이언트 ID를 선택합니다. (Android 클라이언트 ID가 표시되지 않으면 Firebase 콘솔에서 게임의 SHA-1 지문을 설정했는지 확인하세요.)
    3. 변경 사항을 저장합니다.
  6. 테스터 페이지에서 Play 스토어에 게임을 출시하기 전에 게임에 로그인할 수 있어야 하는 사용자의 이메일 주소를 추가합니다.

Play 게임 로그인을 게임에 통합

플레이어를 게임에 로그인하려면 먼저 Google Play 게임 로그인을 통합해야 합니다.

C++ Android 프로젝트에 Play 게임 로그인 지원을 추가하는 가장 쉽고 권장되는 방법은 Google 로그인 C++ SDK 를 사용하는 것입니다.

Google 로그인 C++ SDK를 사용하여 게임에 Play 게임 로그인을 추가하려면 다음을 수행하세요.

  1. C++ SDK도 포함하는 Google 로그인 Unity 플러그인 리포지토리를 복제하거나 다운로드합니다.

  2. Android Studio 또는 gradlew build 를 사용하여 staging/native/ 디렉토리에 포함된 프로젝트를 빌드합니다.

    빌드는 출력을 google-signin-cpp 라는 디렉토리에 복사합니다.

  3. 게임의 기본 코드 메이크 파일에 Google 로그인 C++ SDK를 포함합니다.

    씨메이크

    최상위 CMakeLists.txt 파일에서:

    set(GSI_PACKAGE_DIR "/path/to/google-signin-cpp")
    add_library(lib-google-signin-cpp STATIC IMPORTED) set_target_properties(lib-google-signin-cpp PROPERTIES IMPORTED_LOCATION     ${GSI_PACKAGE_DIR}/lib/${ANDROID_ABI}/libgoogle-signin-cpp.a )
    ...
    target_link_libraries(     ...     lib-google-signin-cpp)

    ndk 빌드

    Android.mk 파일에서:

    include $(CLEAR_VARS)
    LOCAL_MODULE := google-signin-cpp
    GSI_SDK_DIR := /path/to/google-signin-cpp
    LOCAL_SRC_FILES := $(GSI_SDK_DIR)/lib/$(TARGET_ARCH_ABI)/libgoogle-signin-cpp.a
    LOCAL_EXPORT_C_INCLUDES := $(GSI_SDK_DIR)/include
    include $(PREBUILT_STATIC_LIBRARY)
    

  4. 다음으로 C++ SDK에 필요한 Java 도우미 구성 요소를 포함합니다.

    이렇게 하려면 프로젝트 수준 build.gradle 파일에서 SDK 빌드 출력 디렉터리를 로컬 리포지토리로 추가합니다.

    allprojects {
        repositories {
            // ...
            flatDir {
                dirs 'path/to/google-signin-cpp'
            }
        }
    }
    

    그리고 모듈 수준 build.gradle 파일에서 도우미 구성 요소를 종속성으로 선언합니다.

    dependencies {
        implementation 'com.google.android.gms:play-services-auth:20.4.1'
        // Depend on the AAR built with the Google Sign-in SDK in order to add
        // the Java helper classes, which are used by the C++ library.
        compile(name:'google-signin-cpp-release', ext:'aar')
    }
    
  5. 그런 다음 게임에서 Play 게임 로그인을 사용하고 서버 인증 코드를 검색하도록 GoogleSignIn 개체를 구성합니다.

    #include "google_signin.h"
    #include "future.h"
    
    using namespace google::signin;
    
    // ...
    
    GoogleSignIn::Configuration config = {};
    config.web_client_id = "YOUR_WEB_CLIENT_ID_HERE";
    config.request_id_token = false;
    config.use_game_signin = true;
    config.request_auth_code = true;
    
    GoogleSignIn gsi = GoogleSignIn(GetActivity(), GetJavaVM());
    gsi.Configure(config);
    
  6. 마지막으로 SignIn() 을 호출하여 플레이어를 Play 게임에 로그인합니다.

    Future<GoogleSignIn::SignInResult> &future = gsi.SignIn();
    

    SignIn() 에 의해 반환된 Future가 확인되면 결과에서 서버 인증 코드를 얻을 수 있습니다.

    if (!future.Pending()) {
        const GoogleSignIn::StatusCode status =
                static_cast<GoogleSignIn::StatusCode>(future.Status());
        if (status == GoogleSignIn::kStatusCodeSuccess) {
            // Player successfully signed in to Google Play! Get auth code to
            //   pass to Firebase
            const GoogleSignIn::SignInResult result =
                    static_cast<GoogleSignIn::SignInResult>(future.Result());
            const char* server_auth_code = result.User.GetServerAuthCode();
        }
    }
    

Firebase로 인증

플레이어가 Play 게임에 로그인하면 인증 코드를 사용하여 Firebase에 인증할 수 있습니다.

  1. 플레이어가 Play 게임을 사용하여 성공적으로 로그인한 후 플레이어 계정의 인증 코드를 받습니다.

  2. 그런 다음 Play 게임 서비스의 인증 코드를 Firebase 자격 증명으로 교환하고 Firebase 자격 증명을 사용하여 플레이어를 인증합니다.

    firebase::auth::Credential credential =
        firebase::auth::PlayGamesAuthProvider::GetCredential(server_auth_code);
    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);
}
원하는 경우 콜백 함수를 람다가 사용할 수도 있습니다.
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);
}

다음 단계

사용자가 처음 로그인하면 새 사용자 계정이 생성되어 Play 게임 ID에 연결됩니다. 이 새 계정은 Firebase 프로젝트의 일부로 저장되며 프로젝트의 모든 앱에서 사용자를 식별하는 데 사용할 수 있습니다.

게임에서 firebase::auth::User 객체에서 사용자의 Firebase UID를 가져올 수 있습니다.

firebase::auth::User* user = auth->current_user();
if (user != nullptr) {
  std::string playerName = user->displayName();

  // 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를 가져와 사용자가 액세스할 수 있는 데이터를 제어하는 ​​데 사용할 수 있습니다.

사용자의 Play 게임 플레이어 정보를 얻거나 Play 게임 서비스에 액세스하려면 Google Play 게임 서비스 C++ SDK 에서 제공하는 API를 사용하세요.

사용자를 로그아웃하려면 SignOut() 을 호출하십시오.

auth->SignOut();