Google Play Games 로그인 구현하기
레시피 코드로 Google Play Games 로그인을 구현하려면 아래 절차를 순서대로 완료하세요.
시작하기 전에 공통 사전 준비를 마치세요.
전체 흐름
각 단계에서 무엇을 설정하고 무엇을 호출하는지는 아래와 같습니다.
| 순서 | 구분 | 하는 일 |
|---|---|---|
| 1 | 외부 콘솔 | Google Cloud Console과 Google Play Console에서 인증 정보 준비 |
| 2 | Hive 콘솔 | 인증 정보 등록과 Play Games 로그인 활성화 |
| 3 | Hive Axyl SDK | 인증 모듈과 Play Games 로그인 Add-on 설치 |
| 4 | Hive Axyl SDK | SDK 초기화와 모듈 등록 |
| 5 | 레시피 코드 | 레시피 폴더 복사 |
| 6 | 앱 코드 | ClientId와 DeviceKey 준비 |
| 7 | 레시피 코드 | Play Games 자격 증명 소스 준비 |
| 8 | 레시피 코드 | Play Games 로그인 호출 |
| 9 | 앱 코드 | 로그인 결과 처리 |
| 10 | 앱 코드 | 동작 확인 |
클라이언트 ID가 두 종류 나옵니다
Google Cloud Console에서 발급받는 웹 애플리케이션 유형 OAuth 클라이언트 ID와 Hive 콘솔에서 확인하는 Client ID는 서로 다른 값입니다. 앞의 값은 7단계에서 자격 증명 소스에 넣고, 뒤의 값은 6단계에서 레시피 생성자에 넣습니다.
1. Google 외부 콘솔 설정
-
외부 콘솔 Google Cloud Console과 Google Play Console에서 설정합니다.
Google Cloud Console과 Google Play Console에서 로그인에 사용할 인증 정보를 먼저 준비하세요. Hive Axyl 인증 서버는 여기서 만든 웹 애플리케이션 유형 OAuth 클라이언트로 Play Games의 인가 코드를 자격 증명으로 바꿉니다.
준비 순서는 아래와 같습니다.
- 앱 서버가 사용할 HTTPS 리다이렉트 URI를 먼저 정하세요. 자세한 내용은 앱 서버 리다이렉트 URI 준비를 참조하세요.
- Google Cloud Console에서 Android 유형 OAuth 클라이언트를 만들고 앱의 패키지 이름과 서명 키의 SHA-1 인증서 지문을 등록하세요.
- 같은 곳에서 웹 애플리케이션 유형 OAuth 클라이언트를 만들고, 승인된 리디렉션 URI에 1번에서 정한 주소를 등록하세요. 이 클라이언트의 ID와 보안 비밀번호를 복사해 두세요.
- Google Play Console의 Play 게임즈 서비스에서 두 OAuth 클라이언트를 연결하고 Games services 프로젝트 ID를 복사해 두세요.
웹 애플리케이션 유형 클라이언트 ID는 2단계의 Hive 콘솔과 7단계의 자격 증명 소스 양쪽에, 보안 비밀번호는 2단계의 Hive 콘솔에, Games services 프로젝트 ID는 3단계의 Android 매니페스트에 사용합니다.
2. Hive 콘솔 설정
-
Hive 콘솔 Hive 콘솔에서 설정하거나 확인합니다.
상세 절차: Google Play Games 로그인 인증 정보, 로그인 수단 종류
준비한 인증 정보를 Hive 콘솔에 등록하고 Play Games 로그인을 활성화하세요. 로그인 수단이 비활성 상태이면 레시피 호출이 거절됩니다.
| 설정 항목 | 필수 여부 | 확인할 곳 |
|---|---|---|
| Web Client ID와 Web Client Secret 등록 | 필수 | Google Play Games 로그인 인증 정보 |
| Google Play Games 로그인 활성화 | 필수 | 로그인 수단 종류 |
| App ID별 로그인 설정 | 선택 | App ID별 로그인 설정 |
여기서 등록한 설정은 프로젝트에 속한 모든 App ID에 함께 적용됩니다. 특정 App ID에서만 다른 로그인 수단을 노출하려면 App ID별 로그인 설정을 사용하세요. 다만 App ID별 설정 탭에서는 실행 환경이 Android인 App ID에만 Play Games 입력란이 나타납니다.
3. SDK 모듈과 Add-on 설치
-
Hive Axyl SDK Hive Axyl SDK를 앱에서 호출합니다.
상세 절차: 모듈 설치, Add-on 설치와 Android 설정
인증 모듈과 Play Games 로그인 Add-on을 Unity 프로젝트에 설치하세요. Add-on은 Play Games 로그인 화면을 띄우고 인가 코드를 발급받는 Hive Axyl SDK 확장 패키지이며, 7단계에서 준비하는 자격 증명 소스가 이 Add-on을 호출합니다.
| 패키지 | 필요 여부 | 역할 |
|---|---|---|
com.com2usplatform.hiveaxyl.core | 필수 | SDK 초기화와 로그인 세션 관리 |
com.com2usplatform.hiveaxyl.auth | 필수 | 인가 코드 교환, Play Games 자격 증명으로 로그인, 토큰 발급 |
com.com2usplatform.hiveaxyl.auth.addon.gpg | 필수 | Play Games 로그인 화면 표시와 인가 코드 발급 |
com.com2usplatform.hiveaxyl.storage | 권장 | DeviceKey와 세션 토큰의 암호화 저장 |
Add-on 패키지를 설치하지 않으면 레시피의 Play Games 자격 증명 소스가 컴파일 대상에서 빠지므로 앱 코드에서 사용하지 못합니다.
Add-on을 설치한 뒤 Android 매니페스트 템플릿에 1단계에서 복사한 Games services 프로젝트 ID를 선언하세요. 선언하지 않으면 Play Games가 앱을 인식하지 못합니다. 매니페스트에 넣을 내용은 Add-on 설치와 Android 설정에 있습니다.
Play Games SDK 자체의 초기화 코드는 작성하지 않아도 됩니다. Play Games SDK가 앱 시작 시점에 스스로 초기화합니다.
4. SDK 초기화
-
Hive Axyl SDK Hive Axyl SDK를 앱에서 호출합니다.
상세 절차: 모듈 초기화
앱 시작 지점에서 SDK를 한 번 초기화하고 인증, 토큰, Play Games 로그인 모듈을 등록하세요. 레시피는 SDK를 초기화하지 않으므로, 초기화하지 않은 상태에서 호출하면 FailedPrecondition 오류로 실패합니다.
아래는 Play Games 로그인에 필요한 모듈을 등록해 초기화하는 예제 코드입니다.
using Hive.Axyl.Auth;
using Hive.Axyl.Auth.Addon.GPG;
using Hive.Axyl.Core;
using Hive.Axyl.Core.Unity;
using Hive.Axyl.Storage;
var config = CoreConfig.CreateBuilder("{appId}").Build();
HiveBootstrap.Initialize(config, builder =>
{
builder
.AddAuth()
.AddToken()
.AddSecureStorage()
.AddGooglePlayGames();
});
{appId}에는 Hive 콘솔에서 만든 Android App ID를 입력하세요.
AddGooglePlayGames()는 Android에서만 실제로 등록되고 다른 OS와 Unity 에디터에서는 등록을 건너뜁니다. 어느 OS에서 호출해도 오류가 나지 않으므로 분기 없이 등록해도 됩니다.
앱에서 이미 안전한 저장소를 사용한다면 AddSecureStorage()는 등록하지 않아도 됩니다. 이 경우에도 DeviceKey와 세션 토큰을 앱 재시작 뒤에 다시 읽을 수 있어야 합니다.
5. 레시피 코드 설치
- 레시피 코드 레시피 코드를 프로젝트에 복사합니다.
레시피는 패키지가 아니라 프로젝트에 복사해서 사용하는 소스 코드입니다. axyl-samples-unity 저장소에서 아래 항목을 Unity 프로젝트의 Assets/Recipes/ 아래로 복사하세요.
복사할 항목과 역할은 아래와 같습니다.
- Recipes.asmdef: 레시피 공통 어셈블리 정의
- AssemblyInfo.cs: 내부 헬퍼를 다른 레시피 어셈블리에 공개하는 설정
- Helper/: 여러 레시피가 함께 사용하는 공통 코드
- ProviderLogin/:
ProviderLoginRecipe, 결과 유형, 자격 증명 소스 계약 - ProviderLogin.Gpg/:
GooglePlayGamesCredentialSource
앱 코드에서 레시피를 호출하려면 앱 쪽 어셈블리 정의의 references에 아래 어셈블리를 추가하세요. 원본 Recipes.asmdef의 autoReferenced 값이 false이므로 앱 어셈블리가 자동으로 참조하지 않습니다.
MyApp은 앱에서 사용하는 어셈블리 이름으로 바꾸고, 기존 설정과 참조는 유지하세요. Unity 어셈블리는 참조를 전이하지 않으므로 앱 코드가 직접 사용하는 어셈블리를 모두 여기에 적어야 합니다. Hive.Axyl.Core에는 CoreConfig와 HiveError가, Hive.Axyl.Auth에는 AddAuth()와 AddToken()이, Hive.Axyl.Auth.Addon.GPG에는 AddGooglePlayGames()가, Hive.Axyl.Storage에는 AddSecureStorage()가 들어 있습니다. AddSecureStorage()를 등록하지 않는다면 Hive.Axyl.Storage는 적지 않아도 됩니다.
ProviderLogin.Gpg/만 복사하면 컴파일되지 않습니다
GooglePlayGamesCredentialSource는 ProviderLogin/의 자격 증명 소스 계약과 인가 코드 교환 코드를 사용하고, ProviderLoginRecipe는 Helper/의 PKCE 생성 코드와 세션 준비 코드를 사용합니다. Helper/, Recipes.asmdef, AssemblyInfo.cs, ProviderLogin/을 함께 복사하세요.
6. ClientId와 DeviceKey 준비
ProviderLoginRecipe의 생성자는 ClientId와 DeviceKey를 받습니다. ClientId는 공통 사전 준비에서 확인한 값으로, Hive 콘솔이 프로젝트마다 발급합니다. DeviceKey는 Hive Axyl 인증 서버가 로그인 세션을 기기 단위로 구분하는 값이며, 앱이 직접 만들어 보관합니다.
레시피는 DeviceKey를 만들거나 저장하지 않으므로, 아래 조건에 맞게 만들고 관리하세요.
- 기기마다 다른 값. UUID 같은 난수 권장
- 최초 실행 때 한 번 만들어 저장하고, 이후 모든 로그인에서 재사용하는 값
- 22자 이상 64자 이하의 길이
- 공백과 제어 문자를 제외한 ASCII 문자로만 이루어진 값
저장소를 읽지 못했다고 새 DeviceKey로 덮어쓰지 마세요
값이 사라진 것이 아니라 읽기에만 실패했을 수 있습니다. 먼저 저장소 접근 문제를 해결하거나 다시 읽기를 시도하세요.
PKCE 값은 준비하지 않아도 됩니다. 레시피가 호출할 때마다 한 쌍을 직접 만들어 로그인 호출과 토큰 발급 호출에 나누어 전달합니다.
빈 값을 전달하면 예외가 발생합니다
ClientId나 DeviceKey가 비어 있으면 레시피는 결과를 반환하지 않고 ArgumentException을 던집니다. 자격 증명 소스를 null로 전달할 때도 ArgumentNullException을 던집니다. 저장소에서 읽은 값을 그대로 넘기기 전에 비어 있는지 먼저 확인하세요.
7. Play Games 자격 증명 소스 준비
-
레시피 코드 레시피 코드를 앱에서 호출합니다.
상세 절차: Google Play Games 자격 증명 획득
레시피에 로그인할 외부 인증 제공자를 알려 주려면 자격 증명 소스를 만들어 전달해야 합니다. 자격 증명 소스는 Play Games 로그인 화면을 띄워 사용자 식별자와 인증 결과를 받아오는 객체입니다. Play Games 자격 증명 소스는 Play Games가 발급한 인가 코드를 Hive Axyl 인증 서버에서 자격 증명으로 바꾸는 호출까지 수행합니다.
생성자에는 1단계에서 복사해 둔 웹 애플리케이션 유형 OAuth 클라이언트 ID를 넣습니다. Hive 콘솔의 Client ID가 아니므로 두 값을 바꿔 넣지 마세요. 비어 있거나 공백만 있으면 ArgumentException이 발생합니다.
두 번째 인자 forceRefreshToken은 생략하면 false입니다. 이 값을 true로 지정하면 리프레시 토큰을 함께 받는 인가 코드를 요청하며, 사용자에게 동의 화면이 한 번 더 표시됩니다. 앱 서버가 사용자가 앱을 실행하지 않는 동안에도 Google API를 호출해야 할 때만 지정하세요.
리다이렉트 URI는 자격 증명 소스에 전달하지 않습니다. 상세 절차에 나오는 RedirectUri 준비는 Hive Axyl SDK 메서드를 직접 호출할 때만 필요합니다.
8. Play Games 로그인 호출
- 레시피 코드 레시피 코드를 앱에서 호출합니다.
준비한 자격 증명 소스를 LoginWithProviderAsync()에 전달하세요. 레시피가 Play Games에서 자격 증명을 받아 로그인하고 세션까지 활성화합니다. 로그인 화면은 기기에 로그인된 Play Games 프로필이 없을 때만 뜹니다.
앱이 로그인 대기를 직접 중단해야 할 때를 대비해 CancellationTokenSource를 함께 준비하세요.
로그인 화면을 띄운 장면을 벗어나는 것처럼 앱이 먼저 대기를 끝내야 할 때 cancellation.Cancel()을 호출하고, 호출이 끝나면 cancellation.Dispose()로 정리하세요. 사용자가 Play Games 로그인 화면을 닫은 경우에는 호출하지 마세요. 레시피가 UserCanceled로 알려 줍니다.
레시피가 내부에서 수행하는 작업은 아래와 같습니다.
| 구분 | 호출 | 확인할 곳 |
|---|---|---|
| 레시피 코드 | 인증, 토큰, 세션 모듈이 등록되었는지 확인 | 없음 |
| Add-on | IsAuthenticatedAsync()로 Play Games 인증 상태 확인 | Google Play Games 자격 증명 획득 |
| Add-on | 인증 상태가 아니면 SignInAsync()로 Play Games 로그인 화면 표시 | Google Play Games 자격 증명 획득 |
| Add-on | RequestServerSideAccessAsync()로 서버 교환용 인가 코드 확보 | Google Play Games 자격 증명 획득 |
| Hive Axyl SDK | ExchangeProviderTokenAsync()로 인가 코드를 ProviderUserId와 ProviderToken으로 교환 | 외부 인증 코드 교환 |
| 레시피 코드 | PKCE 값 한 쌍을 만들어 로그인 호출과 토큰 발급 호출에 나눠 전달 | 호출 파라미터값 준비 |
| Hive Axyl SDK | LoginProviderAsync()로 Play Games 자격 증명을 전달하고 인가 코드 수신 | 외부 인증 제공자 로그인 |
| Hive Axyl SDK | IssueTokenAsync()로 인가 코드를 액세스 토큰과 리프레시 토큰으로 교환 | 토큰 발급과 세션 활성화 |
| Hive Axyl SDK | SetSession()으로 로그인 세션 활성화 | 토큰 발급과 세션 활성화 |
인가 코드가 두 번 나오지만 서로 다른 값입니다. 앞의 인가 코드는 Play Games가 발급해 Hive Axyl 인증 서버가 Google과 교환하는 값이고, 뒤의 인가 코드는 Hive Axyl 인증 서버가 발급해 액세스 토큰으로 바꾸는 값입니다.
위 표의 상세 절차는 Hive Axyl SDK 메서드를 직접 호출할 때를 기준으로 쓰여 있습니다. PKCE 값을 만드는 작업처럼 레시피가 대신하는 단계는 앱에서 다시 구현하지 마세요. 각 호출이 무엇을 주고받는지 확인할 때만 참조하세요.
모듈이 등록되어 있지 않으면 모듈 확인 단계에서 FailedPrecondition 오류로 멈춥니다. Success가 반환되면 세션까지 준비된 상태이므로 토큰 발급이나 세션 활성화 코드를 따로 호출하지 마세요. 세션은 사용할 수 있는 토큰을 받은 뒤에만 활성화되므로, 실패한 시도는 이미 열려 있던 세션을 건드리지 않습니다.
9. 로그인 결과 처리
-
앱 코드 앱에서 직접 구현합니다.
상세 절차: HiveError 정보
LoginWithProviderOutcome은 Status로 로그인 결과를 알려 줍니다. FailedStep은 진단용 값이므로 앱의 정상 흐름을 분기하는 기준으로 사용하지 마세요.
Status | 확인할 값 | 앱 처리 |
|---|---|---|
Success | PlayerId, IsBlocked | 이용 제한 상태가 아니면 로그인 후 화면으로 이동합니다. |
BusinessOutcome | BusinessOutcome, UnknownOutcomeCode | 거절 사유에 맞게 분기하고, 모르는 값은 실패로 처리해 기록합니다. |
UserCanceled | 없음 | 사용자가 Play Games 로그인 화면을 닫았거나 이어지는 단계에서 인증을 중단한 상태이므로 이전 화면으로 돌아갑니다. |
Failure | Error.Code, Error.TraceId | 기술 문제를 기록하고 재시도 흐름을 제공합니다. |
IsBlocked가 true이면 로그인은 성공했지만 이용이 제한된 계정입니다. 제한 종류와 안내 방법은 이용 제한을 참조하세요.
PlayerId는 Hive Axyl이 사용자 한 명에게 부여하는 고유 식별자입니다. 같은 Play Games 프로필로 다시 로그인하면 같은 값이 돌아오므로, 앱은 이 값으로 사용자의 플레이 데이터를 구분합니다.
오류를 기록할 때는 FailedStep을 함께 남기세요. 값은 None, Resolve, AcquireCredential, LoginProvider, SessionSetup 다섯 가지이며, 어느 단계에서 멈췄는지 알려 줍니다. 인가 코드 교환까지가 AcquireCredential에 포함됩니다.
9.1. 거절 사유 처리
BusinessOutcome 값은 로그인이 성사되지 않은 사유이므로, 값마다 사용자에게 보여 줄 안내가 다릅니다. 레시피는 세 번의 서버 호출에서 나온 거절 사유를 하나의 값으로 묶어 돌려주므로 세 곳을 모두 확인하세요.
ExchangeProviderTokenAsync(): 외부 인증 코드 교환 응답 상태LoginProviderAsync(): 외부 인증 제공자 로그인 응답 상태IssueTokenAsync(): 액세스 토큰과 리프레시 토큰 발급
Play Games Add-on이나 서버가 돌려준 결과를 레시피가 해석하지 못할 때도 Status는 BusinessOutcome이 되고, BusinessOutcome 값은 Unrecognized입니다. 이때는 UnknownOutcomeCode로 두 경우를 구분하세요. 값이 있으면 이 SDK 버전이 모르는 결과 코드라는 뜻이고, 비어 있으면 SDK는 아는 결과지만 레시피가 이름을 붙이지 않았다는 뜻입니다. 어느 쪽이든 위 세 곳에서 찾지 말고 UnknownOutcomeCode와 RawJson을 기록한 뒤 실패로 처리하세요.
레시피는 상세 절차에 적힌 이름을 아래와 같이 바꿔 돌려줍니다.
TerminateService:ServiceTerminatedInvalidClientId:InvalidClientInvalidGrant:InvalidAuthorizationCodeInvalidGrantExpired:ExpiredAuthorizationCodeInvalidGrantCodeChallenge:CodeChallengeMismatchInvalidGrantRefreshToken:InvalidRefreshToken
ProviderConfigNotFound와 ProviderClientInfoNotExists는 2단계의 Hive 콘솔 설정이 비어 있다는 뜻입니다. ProviderTokenError는 Play Games가 발급한 인가 코드를 Google이 거절했다는 뜻이므로 사용자를 다시 인증시키세요. 세 값은 인가 코드 교환과 로그인 호출 양쪽에서 나옵니다.
TemporarilyUnavailable은 Hive Axyl 인증 서버가 판정을 내리지 못하고 요청을 되돌린 상태이므로 같은 요청을 다시 보내세요. 곧바로 반복하지 말고 1초, 3초, 6초처럼 간격을 늘려 가며 재시도하세요.
9.2. 취소와 미지원 환경 처리
Status가 Failure라고 해서 모두 사용자에게 실패로 안내할 것은 아닙니다. 앱이 대기를 중단한 경우와 Play Games 로그인을 실행할 수 없는 환경도 여기로 들어오므로 Error.Code로 구분하세요.
CancellationToken으로 로그인을 취소하면 Error.Code는 HiveErrorCode.Cancelled가 됩니다. 사용자가 Play Games 로그인 화면을 닫은 UserCanceled와는 다른 결과이므로 안내 메시지를 구분하세요.
Error.Code가 HiveErrorCode.Unavailable이면 호출을 끝까지 실행하지 못했다는 뜻이며, 원인은 네 가지입니다.
- Play Games Add-on 미등록: Android가 아닌 OS에서는 Play Games 로그인 버튼을 숨기고, Android에서는 4단계의
AddGooglePlayGames()등록을 확인하세요. - 기기에서 Play Games 로그인 실패: 다른 로그인 수단을 제시하세요.
- 인가 코드를 발급할 로그인 상태 없음: 다른 로그인 수단을 제시하세요.
- 네트워크 단절이나 서비스 일시 중단: 잠시 뒤에 다시 시도하도록 안내하세요.
Error.Code가 HiveErrorCode.FailedPrecondition이면 호출에 필요한 상태가 준비되지 않았다는 뜻입니다. FailedStep이 Resolve이면 4단계에서 인증과 토큰 모듈을 등록하지 않았거나 SDK를 초기화하지 않은 상태입니다. FailedStep이 AcquireCredential이면 Play Games 설정이 갖춰지지 않은 상태이므로 1단계의 Google 외부 콘솔 설정과 3단계의 Android 매니페스트 선언을 다시 확인하세요.
Error.Code가 HiveErrorCode.Internal이면 호출은 성공했지만 응답에 다음 단계에 필요한 값이 없었다는 뜻입니다. 재시도로 해결되지 않으므로 Error.TraceId와 FailedStep을 기록해 두세요.
UnknownOutcomeCode와 RawJson은 사용자에게 표시하지 마세요. 앱 오류 기록이 필요한 경우에만 사용하고, 모르는 결과를 이미 아는 결과로 추정하지 마세요.
10. 동작 확인
- 앱 코드 앱에서 동작을 확인합니다.
실제 Android 기기에서 Play Games 로그인을 확인하세요. Unity 에디터에서는 Play Games 로그인 Add-on이 등록되지 않아 Unavailable 오류가 반환되므로 로그인 화면부터 검증할 수 없습니다.
- Google Cloud Console의 Android 유형 OAuth 클라이언트에 등록한 패키지 이름과 서명 키로 빌드하세요. 값이 다르면 Play Games가 앱을 확인하지 못해 로그인이 끝까지 진행되지 않습니다.
- 기기에 Google 계정이 로그인되어 있는지 확인하고 앱을 실행하세요.
- Play Games 로그인을 실행하고 로그인 화면이 뜨는지 확인한 뒤 로그인을 완료하세요.
Success와PlayerId를 확인하고 로그인 후 화면으로 넘어가는지 확인하세요.- 앱을 완전히 종료한 뒤 다시 실행해 같은 Play Games 프로필로 로그인하고,
PlayerId가 같은지 확인하세요. - Play Games 프로필이 로그인되어 있지 않은 기기에서 로그인 화면이 떴을 때 취소해
UserCanceled가 반환되는지 확인하세요.
기기에 이미 Play Games 프로필이 로그인되어 있으면 3단계에서 로그인 화면이 뜨지 않고 곧바로 다음 단계로 넘어갑니다. 레시피가 인증 상태를 먼저 확인해 필요할 때만 화면을 띄우기 때문입니다.
다음 단계
로그인한 사용자가 앱을 다시 실행할 때 로그인 화면을 건너뛰도록 하려면 자동 로그인을 참조하세요.
이미 로그인한 계정에 다른 로그인 수단을 추가로 연결하려면 외부 인증 제공자 연동 활용 가이드를 참조하세요.
로그인한 계정에서 빠져나와 다른 계정으로 로그인하도록 하려면 로그아웃 활용 가이드를 참조하세요.