X 로그인 구현하기
레시피 코드로 X 로그인을 구현하려면 아래 절차를 순서대로 완료하세요.
시작하기 전에 공통 사전 준비를 마치세요.
전체 흐름
각 단계에서 무엇을 설정하고 무엇을 호출하는지는 아래와 같습니다.
| 순서 | 구분 | 하는 일 |
|---|---|---|
| 1 | 외부 콘솔 | X OAuth 앱과 Callback URI, Scope 준비 |
| 2 | Hive 콘솔 | X 로그인 활성화와 인증 정보 등록 |
| 3 | Hive Axyl SDK | 인증 모듈과 WebAuth Add-on 설치 |
| 4 | Hive Axyl SDK | SDK 초기화와 모듈 등록 |
| 5 | 레시피 코드 | 공통·WebAuth 레시피 폴더 복사 |
| 6 | 앱 코드, 레시피 코드 | Hive Axyl ClientId, DeviceKey, OAuth 설정 준비 |
| 7 | 레시피 코드 | X 자격 증명 소스 준비 |
| 8 | 레시피 코드 | X 로그인 호출 |
| 9 | 앱 코드 | 로그인 결과 처리 |
| 10 | 앱 코드 | 동작 확인 |
Hive Axyl Client ID와 X Client ID를 구분하세요
Hive 콘솔에서 확인하는 ClientId는 ProviderLoginRecipe 생성자에 넣고, X Developer Portal에서 발급받은 OAuth Client ID는 WebAuthOptions.ClientId에 넣습니다. 두 값을 바꾸어 넣으면 X 인증 또는 Hive Axyl 로그인이 실패합니다.
1. X 외부 콘솔 설정
-
외부 콘솔 X Developer Portal에서 설정합니다.
상세 절차: X 로그인 연동
X Developer Portal에서 OAuth 앱의 Client ID와 Callback URI, Scope를 준비하세요.
레시피가 X 인가 URL을 만들고 자격 증명을 교환할 때 사용하는 값과 그 값을 넣는 곳은 아래와 같습니다.
- OAuth Client ID:
WebAuthOptions.ClientId - Callback URI:
WebAuthOptions.RedirectUri와 X Developer Portal의 허용 목록 - Scope:
WebAuthOptions.Scope - Authorization endpoint:
WebAuthOptions.AuthorizeEndpoint - Token endpoint: 공개 클라이언트 방식의
WebAuthOptions.TokenEndpoint - User information endpoint: 공개 클라이언트 방식의
WebAuthOptions.UserInfoEndpoint
아래는 X 개발자 문서의 OAuth 2.0 Authorization Code Flow with PKCE와 GET /2/users/me를 기준으로 한 값의 예시입니다.
- Authorization endpoint:
https://x.com/i/oauth2/authorize - Scope:
tweet.read users.read - Token endpoint:
https://api.x.com/2/oauth2/token - User information endpoint:
https://api.x.com/2/users/me
Scope와 엔드포인트는 앱의 X OAuth 설정과 요청할 사용자 정보 범위에 맞게 X 개발자 문서에서 확인하세요. Callback URI는 X Developer Portal에 등록한 값과 앱 설정에 넣는 값이 정확히 같아야 합니다.
X Client Secret은 공개 클라이언트 앱에 넣지 마세요. 서버 교환 방식을 사용할 때의 Secret은 Hive 콘솔에만 등록합니다.
2. Hive 콘솔 설정
-
Hive 콘솔 Hive 콘솔에서 설정하거나 확인합니다.
상세 절차: X(Twitter) 로그인 인증 정보, 로그인 수단 종류
X 로그인 인증 정보를 등록하고 로그인 수단을 활성화하세요. 설정이 비어 있거나 로그인 수단이 비활성화되어 있으면 레시피의 Hive Axyl 로그인 단계가 거절됩니다.
아래 항목을 설정합니다.
| 설정 항목 | 필수 여부 | 확인할 곳 |
|---|---|---|
| X Client ID 등록 | 필수 | X(Twitter) 로그인 인증 정보 |
| X Client Secret 등록 | 서버 교환 방식을 사용할 때 필수 | X(Twitter) 로그인 인증 정보 |
| X(Twitter) 로그인 활성화 | 필수 | 로그인 수단 종류 |
| App ID별 로그인 설정 | 선택 | App ID별 로그인 설정 |
공개 클라이언트 방식에서는 레시피가 X의 토큰 엔드포인트와 직접 교환하므로 Client Secret을 앱에 전달하지 않습니다. Hive 콘솔에는 프로젝트의 X 로그인 인증 정보를 등록해 로그인 수단을 활성화하고, 서버 교환 방식을 선택할 때 사용할 Secret을 보관하세요.
3. SDK 모듈과 Add-on 설치
-
Hive Axyl SDK Hive Axyl SDK를 앱에서 호출합니다.
상세 절차: 모듈 설치, X 로그인 Add-on 설치
X 로그인에 필요한 Hive Axyl SDK 모듈과 WebAuth Add-on을 Unity 프로젝트에 설치하세요.
| 패키지 | 필요 여부 | 역할 |
|---|---|---|
com.com2usplatform.hiveaxyl.core | 필수 | SDK 초기화와 공통 오류 처리 |
com.com2usplatform.hiveaxyl.auth | 필수 | X 자격 증명으로 로그인하고 토큰 발급 |
com.com2usplatform.hiveaxyl.storage | 권장 | DeviceKey와 세션 토큰의 암호화 저장 |
com.com2usplatform.hiveaxyl.auth.addon.webauth | 필수 | 브라우저 웹 로그인 세션 제공 |
com.unity.nuget.newtonsoft-json | 필수 | ProviderLogin.WebAuth/의 JSON 처리 |
WebAuth Add-on 패키지를 설치하지 않으면 ProviderLogin.WebAuth/ 레시피 어셈블리가 컴파일 대상에서 빠지므로 XCredentialSource를 사용하는 앱 코드가 컴파일되지 않습니다. 패키지를 설치했더라도 AddWebAuth()를 등록하지 않았거나 Unity 에디터에서 실행하면 X 자격 증명 소스가 Unavailable을 반환합니다. 패키지 설치 후에는 모듈 초기화에서 AddWebAuth()도 등록하세요.
4. SDK 초기화
-
Hive Axyl SDK Hive Axyl SDK를 앱에서 호출합니다.
상세 절차: 모듈 초기화
앱 시작 지점에서 인증, 토큰, 보안 저장소, WebAuth 모듈을 한 번 등록하세요. 레시피는 SDK를 초기화하지 않습니다.
using Hive.Axyl.Auth;
using Hive.Axyl.Auth.Addon.WebAuth;
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()
.AddWebAuth();
});
{appId}에는 Hive 콘솔에서 만든 App ID를 입력하세요. AddWebAuth()는 지원하는 OS에서만 실제 모듈을 등록하며, Unity 에디터에서는 등록하지 않습니다.
5. 레시피 코드 설치
- 레시피 코드 레시피 코드를 프로젝트에 복사합니다.
레시피는 패키지가 아니라 프로젝트에 복사해서 사용하는 소스 코드입니다. axyl-samples-unity 저장소에서 아래 항목을 Unity 프로젝트의 Assets/Recipes/ 아래로 복사하세요.
복사할 항목과 역할은 아래와 같습니다.
- Recipes.asmdef: 레시피 공통 어셈블리 정의
- AssemblyInfo.cs: 내부 헬퍼를 다른 레시피 어셈블리에 공개하는 설정
- Helper/: 여러 레시피가 함께 사용하는 공통 코드
- ProviderLogin/:
ProviderLoginRecipe, 결과 유형, 자격 증명 소스 계약 - ProviderLogin.WebAuth/:
XCredentialSource와 브라우저 로그인 공통 코드
앱 코드에서 레시피를 호출하려면 앱 어셈블리 정의의 references에 아래 어셈블리를 추가하세요.
MyApp은 앱에서 사용하는 어셈블리 이름으로 바꾸고 기존 설정과 참조는 유지하세요. Unity 어셈블리는 참조를 전이하지 않으므로 앱 코드가 직접 사용하는 어셈블리를 모두 적어야 합니다. ProviderLogin.WebAuth/를 사용할 때는 com.unity.nuget.newtonsoft-json 패키지도 설치해야 합니다.
공통 레시피 폴더를 함께 복사하세요
ProviderLogin.WebAuth/는 ProviderLogin/의 자격 증명 소스 계약을 구현하고, ProviderLoginRecipe는 Helper/의 공통 코드를 사용합니다. Helper/, Recipes.asmdef, AssemblyInfo.cs, ProviderLogin/을 함께 복사하세요.
6. ClientId, DeviceKey와 OAuth 설정 준비
-
앱 코드 앱에서 직접 구현합니다.
레시피 코드 레시피 코드를 앱에서 호출합니다.
상세 절차: Client ID, deviceKey, 리다이렉트 URI 준비
ProviderLoginRecipe의 생성자는 ClientId와 DeviceKey를 받습니다. ClientId는 공통 사전 준비에서 확인한 값으로, Hive 콘솔이 프로젝트마다 발급합니다. DeviceKey는 Hive Axyl 인증 서버가 로그인 세션을 기기 단위로 구분하는 값이며, 앱이 직접 만들어 보관합니다. XCredentialSource에는 X OAuth 설정을 담은 WebAuthOptions를 전달합니다.
| 값 | 넣는 곳 | 준비 방법 |
|---|---|---|
Hive Axyl ClientId | new ProviderLoginRecipe(clientId, deviceKey) | Hive 콘솔의 보안 키에서 확인 |
DeviceKey | new ProviderLoginRecipe(clientId, deviceKey) | 앱이 생성해 보관 |
| X OAuth Client ID | WebAuthOptions.Create()의 clientId | X Developer Portal에서 확인 |
| Authorization endpoint | WebAuthOptions.Create()의 authorizeEndpoint | X OAuth 설정에서 확인 |
| Callback URI | WebAuthOptions.Create()의 redirectUri | X Developer Portal에 등록한 값과 동일하게 설정 |
| Scope | WebAuthOptions.Create()의 scope | X Developer Portal에서 허용한 범위에 맞게 설정 |
레시피는 DeviceKey를 만들거나 저장하지 않으므로, 아래 조건에 맞게 만들고 관리하세요.
- 기기마다 다른 값. UUID 같은 난수 권장
- 최초 실행 때 한 번 만들어 저장하고, 이후 모든 로그인에서 재사용하는 값
- 22자 이상 64자 이하의 길이
- 공백과 제어 문자를 제외한 ASCII 문자로만 이루어진 값
저장소를 읽지 못했다고 새 DeviceKey로 덮어쓰지 마세요
값이 사라진 것이 아니라 읽기에만 실패했을 수 있습니다. 먼저 저장소 접근 문제를 해결하거나 다시 읽기를 시도하세요.
ClientId나 DeviceKey가 비어 있으면 레시피 생성자에서 ArgumentException이 발생합니다. WebAuthOptions의 필수값이 비어 있어도 생성 시 예외가 발생하므로 설정을 읽은 뒤 검증하세요.
X는 PKCE를 필수로 요구합니다. 레시피가 로그인 시도마다 X용 PKCE를 만들고 콜백의 state를 검증하므로 앱에서 PKCE와 state를 다시 만들지 마세요.
6.1. 리다이렉트 URI 선택
콜백을 받을 리다이렉트 URI에 따라 WebAuthOptions를 만드는 메서드가 다릅니다. X Developer Portal에 등록한 고정 Callback URI는 WebAuthOptions.Create()로, Windows에서 실행할 때마다 포트가 달라지는 로컬 주소는 WebAuthOptions.WithLoopbackRedirect()로 지정합니다.
6.1.1. 고정 Callback URI
아래는 고정 Callback URI로 X OAuth 설정을 만드는 예제 코드입니다.
{xRedirectUri}는 X Developer Portal의 Callback URI와 같아야 합니다. Android는 리다이렉트 URI 준비에 따라 launcherTemplate.gradle에 URL 스킴을 설정하세요. iOS와 macOS는 추가 설정이 필요하지 않으며, 스킴이 있는 Callback URI를 사용합니다.
6.1.2. Windows 로컬 주소
Windows에서는 WebAuth Add-on이 실행할 때마다 포트가 달라지는 로컬 주소로 콜백을 받습니다. X가 가변 포트의 로컬 주소 리다이렉트를 허용하면 WebAuthOptions.Create() 대신 WebAuthOptions.WithLoopbackRedirect()에 /hive-auth/callback 같은 경로를 지정하세요. 레시피가 로그인할 때마다 로컬 주소를 예약해 인가 요청에 넣습니다. X Developer Portal에 등록할 주소는 허용 목록에 등록할 주소를 참조하세요. WithLoopbackRedirect()로 만든 설정은 로컬 주소를 예약할 수 있는 Windows에서만 동작합니다.
6.2. 공개 클라이언트의 토큰 교환
X OAuth 클라이언트가 Client Secret을 발급하지 않는 공개 클라이언트라면 tokenEndpoint와 userInfoEndpoint를 지정하세요. 레시피가 X 토큰 엔드포인트에서 access_token을 받고 사용자 정보 엔드포인트에서 data.id를 읽습니다.
tokenEndpoint를 비워 두면 레시피가 Hive Axyl SDK의 ExchangeProviderTokenAsync()를 사용합니다. 이 경우 Hive 콘솔의 X Client Secret을 사용해 Hive Axyl 인증 서버가 X와 교환합니다. 두 경로 중 하나만 선택하고 Client Secret을 앱 코드에 넣지 마세요.
7. X 자격 증명 소스 준비
-
레시피 코드 레시피 코드를 앱에서 호출합니다.
상세 절차: X 자격 증명 획득
준비한 WebAuthOptions로 XCredentialSource를 만든 뒤 레시피에 전달하세요.
XCredentialSource는 X 인가 URL을 만들고 WebAuth Add-on을 호출합니다. 앱은 OpenAsync()를 직접 호출하거나 X용 PKCE를 다시 만들지 마세요. WebAuth Add-on의 세션과 취소 처리는 웹 로그인 세션을 참조하세요.
8. X 로그인 호출
- 레시피 코드 레시피 코드를 앱에서 호출합니다.
준비한 자격 증명 소스를 LoginWithProviderAsync()에 전달하세요. 레시피가 X 자격 증명 획득, Hive Axyl 로그인, 토큰 발급, 세션 활성화를 이어서 수행합니다.
로그인 화면을 닫는 것처럼 앱이 대기를 중단해야 할 때 cancellation.Cancel()을 호출하고, 호출이 끝나면 cancellation.Dispose()로 정리하세요. Android, iOS, macOS에서 사용자가 X 화면을 닫은 경우에는 취소 토큰을 호출하지 말고 레시피가 반환하는 UserCanceled를 처리하세요.
Windows에서는 외부 브라우저를 사용하므로 사용자가 브라우저를 닫아도 레시피가 이를 감지하지 못하고 계속 기다립니다. 로그인 화면에 취소 버튼을 두어 cancellation.Cancel()을 호출하거나, new CancellationTokenSource(TimeSpan.FromMinutes(5))처럼 제한 시간을 지정하세요. TimeSpan을 사용하려면 using System;을 추가하세요. 자세한 내용은 웹 로그인 세션 열기의 응답 상태를 참조하세요.
레시피가 내부에서 수행하는 작업은 아래와 같습니다.
| 구분 | 호출 | 확인할 곳 |
|---|---|---|
| 레시피 코드 | 인증, 토큰, 세션 모듈이 등록되었는지 확인 | 모듈 초기화 |
| Add-on | Windows에서 AllocateLoopbackRedirectUriAsync()로 콜백을 받을 로컬 주소 예약 | 리다이렉트 URI 준비 |
| 레시피 코드 | X 인가 URL, state, X용 PKCE 생성 | 인가 URL 구성 |
| Add-on | OpenAsync()로 X 로그인 페이지를 열고 콜백 수신 | 웹 로그인 세션 열기 |
| 레시피 코드 | 콜백 state 검증 | 콜백 확인 |
| Hive Axyl SDK | tokenEndpoint를 비워 둔 경우 ExchangeProviderTokenAsync()로 X 인가 코드 교환. RedirectUri에는 인가 요청에 사용한 리다이렉트 URI를, CodeVerifier에는 X가 필수로 요구하는 X용 PKCE 값을 넣음 | 외부 인증 코드 교환 |
| 레시피 코드 | tokenEndpoint를 지정한 경우 X 토큰 엔드포인트와 사용자 정보 엔드포인트를 직접 호출 | 공개 클라이언트의 토큰 교환 |
| Hive Axyl SDK | LoginProviderAsync()에 준비된 X 자격 증명 전달 | 외부 인증 제공자 로그인 |
| Hive Axyl SDK | IssueTokenAsync()로 Hive Axyl 토큰 발급, SetSession()으로 세션 활성화 | 토큰 발급과 세션 활성화 |
위 표의 SDK 메서드는 레시피가 내부에서 호출합니다. 레시피를 사용하는 앱은 ExchangeProviderTokenAsync(), LoginProviderAsync(), IssueTokenAsync(), SetSession()을 다시 호출하지 마세요. X용 PKCE와 Hive Axyl용 PKCE는 서로 다른 값이며, 둘 다 레시피가 관리합니다.
tokenEndpoint를 지정한 공개 클라이언트 방식의 HTTP 요청은 레시피가 X에 직접 보냅니다. 이 요청은 Hive Axyl Server API 호출이 아니며, Client Secret도 포함하지 않습니다.
9. 로그인 결과 처리
-
앱 코드 앱에서 직접 구현합니다.
상세 절차: HiveError 정보
LoginWithProviderOutcome의 Status를 먼저 확인하고, 나머지 값을 상태에 맞게 읽으세요. FailedStep은 진단용 값이므로 정상 흐름의 분기 기준으로 사용하지 마세요.
Status | 확인할 값 | 앱 처리 |
|---|---|---|
Success | PlayerId, IsBlocked | 이용 제한 상태가 아니면 로그인 후 화면으로 이동합니다. |
BusinessOutcome | BusinessOutcome, UnknownOutcomeCode | 거절 사유에 맞게 분기하고, 모르는 값은 실패로 처리해 기록합니다. |
UserCanceled | 없음 | 사용자가 X 로그인 화면을 닫거나 동의를 거부한 상태이므로 로그인 화면을 유지합니다. |
Failure | Error.Code, Error.TraceId | 기술 문제를 기록하고 재시도 또는 다른 로그인 수단을 제공합니다. |
Success의 PlayerId는 같은 X 계정으로 다시 로그인할 때도 같은 값입니다. IsBlocked가 true이면 로그인은 성공했지만 이용이 제한된 계정이므로 이용 제한을 기준으로 안내하세요.
UserCanceled와 Failure의 Cancelled를 구분하세요. 사용자가 X 인증 화면을 닫거나 동의를 거부하면 UserCanceled이고, 앱이 CancellationToken으로 대기를 중단하면 Failure와 HiveErrorCode.Cancelled입니다. Windows에서는 사용자가 브라우저를 닫아도 UserCanceled가 반환되지 않으므로 앱의 취소 처리로 대기를 끝내야 합니다.
| 상황 | 레시피 결과 | 앱 처리 |
|---|---|---|
| 사용자가 X 인증 화면에서 동의를 거부함 | UserCanceled | 로그인 화면 유지 |
| Windows 외 OS에서 사용자가 X 인증 화면을 닫음 | UserCanceled | 로그인 화면 유지 |
| WebAuth Add-on이 등록되지 않음 | Failure와 Unavailable | 3단계 설치와 4단계 AddWebAuth() 등록 확인 |
콜백의 state가 현재 로그인 요청과 다름 | Failure와 PermissionDenied | 이번 로그인에서 시작하지 않은 콜백이므로 로그인 화면을 유지하고 다시 시도할 수 있게 함 |
| 공개 클라이언트의 토큰·사용자 정보 요청 실패 | Failure | X 엔드포인트, Scope, Client ID, 네트워크 상태 확인 |
| Hive Axyl 서버가 X 자격 증명을 거부함 | BusinessOutcome 또는 Failure | X 콘솔과 Hive 콘솔 설정, 인증 만료 여부 확인 |
| 앱이 대기를 취소함 | Failure와 Cancelled | 진행 중인 로그인 화면을 정리하고 로그인 화면 유지 |
BusinessOutcome에는 ProviderConfigNotFound, ProviderClientInfoNotExists, ProviderTokenError, InvalidAuthorizationCode, ExpiredAuthorizationCode, CodeChallengeMismatch, TemporarilyUnavailable 등이 포함될 수 있습니다. 레시피는 여러 호출의 거절 사유를 하나의 값으로 묶어 돌려주므로 외부 인증 제공자 로그인 응답 상태와 액세스 토큰과 리프레시 토큰 발급을 확인하세요. 서버 교환을 사용하면 외부 인증 코드 교환 응답 상태도 확인하세요. TemporarilyUnavailable만 1초, 3초, 6초처럼 간격을 늘려 가며 재시도하고, 나머지는 설정이나 인증 상태를 먼저 확인하세요.
X 인가 코드, 액세스 토큰, WebAuth 콜백 URL은 로그, 크래시 리포트, 분석 이벤트에 남기지 마세요. UnknownOutcomeCode와 RawJson은 사용자에게 표시하지 말고, 앱 오류 기록이 필요한 경우에만 사용하세요.
10. 동작 확인
- 앱 코드 앱에서 동작을 확인합니다.
WebAuth는 Unity 에디터에서 실제 인증 화면을 제공하지 않으므로 지원하는 기기와 빌드에서 확인하세요.
- X Developer Portal과 Hive 콘솔 설정을 저장한 뒤 대상 OS로 앱을 빌드하세요.
- X 로그인 화면이 열리고 Callback URI를 통해 앱으로 돌아오는지 확인하세요.
- Windows에서는 레시피가
WithLoopbackRedirect()설정으로 예약한 로컬 주소로 콜백이 돌아오는지 확인하세요. Success와PlayerId를 확인하고 로그인 후 화면으로 이동하는지 확인하세요.- 앱을 완전히 종료한 뒤 같은 X 계정으로 다시 로그인해
PlayerId가 같은지 확인하세요. - Android, iOS, macOS에서는 인증 화면을 닫아
UserCanceled가 반환되는지 확인하세요. Windows에서는 동의를 거부해UserCanceled를 확인하고, 취소 버튼이나 제한 시간으로Failure와Cancelled가 반환되는지 확인하세요.
다음 단계
로그인한 사용자가 앱을 다시 실행할 때 로그인 화면을 건너뛰도록 하려면 자동 로그인을 참조하세요.
이미 로그인한 계정에 다른 로그인 수단을 연결하려면 외부 인증 제공자 연동을 참조하세요.
로그인한 계정에서 빠져나와 다른 계정으로 로그인하려면 로그아웃을 참조하세요.