웹 로그인 세션
웹 로그인 세션은 전용 Add-on이 없는 외부 인증 제공자와 OS 조합에서 자격 증명을 받아 오는 공용 수단입니다. 앱이 만든 인가 URL을 OS가 제공하는 인증 전용 브라우저 세션으로 열고, 인증이 끝난 뒤 되돌아오는 리다이렉트 콜백을 앱에 전달합니다.
웹 로그인 세션은 OAuth 규격을 해석하지 않고 콜백 URL과 그 쿼리 파라미터를 그대로 돌려줍니다. 따라서 인가 URL 만들기, PKCE 값과 state 값 생성 및 검증, 콜백에서 인가 코드 꺼내기는 모두 앱 클라이언트가 직접 처리합니다.
state는 로그인을 시도할 때마다 새로 만드는 난수입니다. 이 값을 인가 URL에 담아 보내고 콜백으로 돌아온 state와 비교하세요. 그러면 앱이 시작하지 않은 인증 결과가 들어오는 것을 막을 수 있습니다. 특히 Windows는 콜백을 로컬 주소로 받으므로, 같은 기기의 다른 프로그램이 해당 주소로 가짜 응답을 보낼 수 있습니다. state 검증을 반드시 구현하세요.
사용하려면 모듈 설치 및 초기화에서 com.com2usplatform.hiveaxyl.auth.addon.webauth를 설치하고 AddWebAuth()로 등록하세요.
1. 리다이렉트 URI 준비
리다이렉트 URI는 외부 인증 제공자가 인증을 마친 뒤 사용자를 되돌려 보낼 주소입니다. 이 주소가 앱으로 정확히 돌아오지 않으면 콜백을 받지 못해 로그인이 실패합니다.
앱에서 사용할 리다이렉트 URI를 먼저 정한 뒤, 제공자 콘솔의 허용 목록에 등록하세요. 등록 절차는 사전 준비를, Hive 콘솔의 로그인 수단 등록은 로그인 설정을 참조하세요. 앱이 콜백을 받는 방식은 OS마다 다르며, 외부 인증 제공자의 응답이 앱으로 바로 돌아오지 못하는 조합은 Hive Axyl 중계 주소를 거칩니다.
1.1. Android
Android는 앱 고유의 URL 스킴으로 콜백을 받습니다. 웹 로그인 세션 Add-on에는 콜백을 받는 화면과 인텐트 필터가 이미 들어 있고, 인텐트 필터의 스킴은 빌드할 때 Gradle 설정 값으로 정해집니다. OpenRequest.RedirectUri로는 Android의 콜백 스킴을 바꿀 수 없으므로, 앱이 콜백으로 받을 스킴을 빌드 설정에 미리 넣어 두세요.
Unity 에디터의 Project Settings > Player > Android > Publishing Settings > Build에서 Custom Launcher Gradle Template을 켜면 Assets/Plugins/Android/launcherTemplate.gradle 파일이 생성됩니다. 이 파일의 defaultConfig에 hiveAxylWebAuthRedirectScheme 값을 지정하세요. 이 값을 mainTemplate.gradle에 넣으면 Android 빌드가 실패합니다. 아래 예시처럼 com.myapp.oauth를 지정했다면 com.myapp.oauth://callback처럼 이 스킴으로 시작하는 주소를 리다이렉트 URI로 사용합니다.
App ID 스킴 등록
Hive Axyl 중계 주소를 거치는 로그인을 Android에서 제공한다면, 중계 주소가 보내는 콜백을 받을 수 있도록 App ID도 스킴으로 등록해야 합니다. 필요한 스킴이 App ID 하나뿐이라면 hiveAxylWebAuthRedirectScheme에 App ID를 지정하세요.
여러 스킴 등록
hiveAxylWebAuthRedirectScheme에는 스킴을 하나만 지정합니다. Hive Axyl 중계 주소의 앱 콜백 스킴과 다른 로그인 수단의 리다이렉트 URI 스킴처럼 스킴이 두 개 이상 필요하면, 하나는 hiveAxylWebAuthRedirectScheme에 지정하고 나머지는 앱이 소유한 Android 라이브러리의 매니페스트에서 같은 콜백 화면에 인텐트 필터로 추가하세요.
아래 예시는 hiveAxylWebAuthRedirectScheme에 다른 로그인 수단의 스킴 com.myapp.oauth를 지정한 상태에서 매니페스트에 App ID 스킴을 추가하는 경우입니다. {appId}에는 SDK를 초기화할 때 사용한 Hive 콘솔의 App ID를 넣습니다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name="com.com2usplatform.hiveaxyl.auth.addon.webauth.HiveAxylWebAuthCallbackActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="{appId}" />
</intent-filter>
</activity>
</application>
</manifest>
1.2. iOS와 macOS
추가 설정이 필요하지 않습니다. OpenRequest.RedirectUri에 넣은 주소의 스킴을 OS 인증 세션이 그대로 사용하므로, Info.plist에 URL 스킴을 등록하지 않아도 콜백을 받습니다.
1.3. Windows
Windows는 앱이 잠시 여는 로컬 주소로 콜백을 받습니다. 이 주소는 실행할 때마다 달라지므로, 인가 URL을 만들기 직전에 AllocateLoopbackRedirectUriAsync()를 호출해 주소를 예약하고 그 값을 인가 URL과 OpenRequest.RedirectUri에 똑같이 사용하세요.
using Hive.Axyl.Auth.Addon.WebAuth;
using Hive.Axyl.Core;
// WindowsLoopback은 Windows 빌드에서만 값을 가집니다.
if (!HiveCore.TryResolve<IExternalUserAgent>(out var agent)
|| agent is not WebAuthSessionPlugin { WindowsLoopback: { } loopback })
{
// Windows가 아니거나 Add-on이 등록되지 않은 경우
return;
}
var allocated = await loopback.AllocateLoopbackRedirectUriAsync(
new AllocateLoopbackRedirectUriRequest { PathPrefix = "/hive-auth/callback" });
if (allocated is not WindowsLoopbackServiceAllocateLoopbackRedirectUriResult.Success success)
{
// 주소 예약 실패 → 로그인 화면 유지
return;
}
// 예: http://127.0.0.1:54321/hive-auth/callback
string redirectUri = success.Data.RedirectUri;
PathPrefix에는 리다이렉트 URI의 경로 부분을 지정합니다. 값을 넣을 때는 /로 시작해야 하며, 빈 문자열을 넣으면 기본 경로를 사용합니다. AllocateLoopbackRedirectUriAsync()를 다시 호출하면 이전에 예약한 주소는 무효가 됩니다. 이 메서드를 먼저 호출하지 않았거나 OpenRequest.RedirectUri가 마지막으로 예약한 주소와 다르면 OpenAsync()가 Failure로 끝나고 Failure.Problem.Code에 FailedPrecondition이 담깁니다.
허용 목록에 등록할 주소
예약된 주소의 포트 번호는 실행할 때마다 달라지므로, 외부 인증 제공자 콘솔의 허용 목록에는 포트를 지정하지 않은 로컬 주소를 등록하세요. Apple은 로컬 주소를 리다이렉트 URI로 허용하지 않으므로, Windows의 Apple 로그인은 Hive Axyl 중계 주소를 거쳐 예약한 로컬 주소로 콜백을 받습니다.
1.4. Hive Axyl 중계 주소
일부 외부 인증 제공자는 앱 고유 스킴이나 로컬 주소로 사용자를 되돌려 보내지 않습니다. 이때는 Hive Axyl이 운영하는 HTTPS 중계 주소가 외부 인증 제공자의 응답을 받아 앱으로 전달합니다.
중계 주소를 거치는 조합은 아래와 같습니다. 각 조합의 요청 구성과 콜백 처리는 Apple로 로그인과 Steam 계정으로 로그인을 참조하세요.
- Android와 Windows의 Apple 로그인
- Android와 iOS의 Steam 로그인
중계 주소와 앱 콜백 주소
Hive Axyl 중계 주소는 https://core-api.hiveaxyl.com/auth/v1/provider/callback이며, 외부 인증 제공자에게 보내는 요청에 넣습니다. Apple에서는 인가 URL의 redirect_uri에 이 주소를 넣고, Steam에서는 이 주소 뒤에 쿼리 파라미터를 붙여 로그인 요청의 openid.return_to를 만듭니다.
앱 콜백 주소는 Hive Axyl 중계 주소가 인증 결과를 전달할 앱의 주소이며, OpenRequest.RedirectUri에는 중계 주소가 아니라 이 주소를 넣습니다. Android와 iOS에서는 {appId}://oauth-callback 형식을 사용하며, {appId}에는 Android 패키지 이름이 아니라 SDK를 초기화할 때 사용한 Hive 콘솔의 App ID를 넣습니다. Windows에서는 AllocateLoopbackRedirectUriAsync()로 예약한 로컬 주소가 앱 콜백 주소입니다.
역할 분담
중계 주소를 거치는 로그인에서 Hive Axyl이 처리하는 일은 아래와 같습니다.
- 중계 주소 운영
- 등록된 앱 정보를 기준으로 한 App ID와 전달 대상 확인
- 외부 인증 제공자 응답을 앱 콜백 주소로 전달
- Steam 로그인 결과의 진위 검증과 Apple 인가 코드 교환
앱이 처리하는 일은 아래와 같습니다. 외부 인증 제공자 쪽에 중계 주소를 등록하는 일은 Apple 로그인에만 해당하며, Steam에는 중계 주소를 등록하지 않습니다.
- Apple 로그인용 Service ID의 Return URL과 도메인 등록
- 중계 주소를 넣은 로그인 요청 구성
- Android의 App ID 스킴 등록
- 콜백 검증과 로그인 값 추출
- 검증 실패, 사용자 취소, 교환 실패 시 로그인 중단
플랫폼별 콜백 설정
Android에서는 App ID를 콜백 스킴으로 등록해야 Hive Axyl 중계 주소가 보낸 콜백이 앱으로 돌아옵니다. 등록 방법은 App ID 스킴 등록을 참조하세요. iOS는 OpenRequest.RedirectUri의 스킴을 OS 인증 세션이 그대로 사용하므로 추가 설정이 필요하지 않습니다.
2. 웹 로그인 세션 열기
OpenAsync
OpenAsync()를 호출해 인가 URL을 인증 전용 브라우저 세션으로 열고 리다이렉트 콜백을 받습니다. 한 번에 하나의 세션만 열 수 있으며, 진행 중인 세션이 있는 상태에서 다시 호출하면 진행 중인 세션을 유지한 채 Failure를 반환합니다.
호출 파라미터
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| request | OpenRequest | Required | 웹 로그인 세션 요청 |
| ct | CancellationToken | Optional | 취소 토큰. 세션 자체에는 기본 제한 시간이 없으므로, CancellationTokenSource(TimeSpan)으로 앱이 제한 시간을 직접 정하세요. |
OpenRequest
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Url | string | Required | 앱이 만든 인가 URL. 각 외부 인증 제공자가 정한 규격을 따릅니다. |
RedirectUri | string | Required | 리다이렉트 URI 준비에서 정한 주소. 인가 URL에 넣은 값과 같아야 합니다. Hive Axyl 중계 주소를 거치는 조합에서는 인가 URL에 넣은 중계 주소가 아니라 앱 콜백 주소를 넣습니다. |
Url이나 RedirectUri가 비어 있으면 ArgumentException이 발생합니다.
호출 예시
요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.
using Hive.Axyl.Auth.Addon.WebAuth;
using Hive.Axyl.Core;
using UnityEngine;
// 웹 로그인 세션은 지원하는 OS 빌드에서만 등록됩니다.
if (!HiveCore.TryResolve<IExternalUserAgent>(out var webAuth))
{
return;
}
// authorizationUrl과 redirectUri는 앱이 만들어 보관한 값입니다.
var result = await webAuth.OpenAsync(new OpenRequest {
Url = authorizationUrl,
RedirectUri = redirectUri,
});
switch (result)
{
case ExternalUserAgentServiceOpenResult.Success success:
// 콜백 쿼리 파라미터에서 인가 코드를 꺼내 다음 단계로 넘깁니다.
string providerCode = success.Data.Parameters["code"];
break;
case ExternalUserAgentServiceOpenResult.UserCanceled:
// 사용자가 인증 창을 닫음 → 로그인 화면 유지
break;
case ExternalUserAgentServiceOpenResult.Failure failure:
HiveError err = failure.Problem;
Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
break;
// 안전망: 처리하지 않은 결과 및 알 수 없는 신규 결과(UnknownOutcome)
default:
Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
break;
}
Warning
콜백 파라미터에는 인가 코드가 그대로 들어 있습니다. Data.CallbackUrl과 Data.Parameters는 로그, 크래시 리포트, 분석 이벤트에 남기지 마세요.
응답 데이터
성공 시 ExternalUserAgentServiceOpenResult.Success의 Data(OpenResponse)에 콜백 결과가 담깁니다.
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Data.CallbackUrl | string | Required | 리다이렉트된 콜백 URL 원문 |
Data.Parameters | IReadOnlyDictionary<string, string> | Required | 콜백 URL의 쿼리 파라미터를 파싱한 값 |
외부 인증 제공자가 인증 실패를 콜백으로 알리는 경우도 있습니다. 이때는 세션이 Success로 끝나고 Data.Parameters에 error 같은 파라미터가 담기므로, 인가 코드를 꺼내기 전에 파라미터 내용을 확인하세요.
응답 예시
응답 상태
ExternalUserAgentServiceOpenResult의 응답 케이스는 switch 구문으로 처리하는 것을 권장합니다.
| 응답 케이스 | 설명 | 앱 클라이언트 대응 |
|---|---|---|
Success | 콜백을 수신한 경우. Data.Parameters에서 인가 코드를 꺼냅니다. | 인가 코드를 다음 단계로 전달 |
UserCanceled | 사용자가 인증 창을 닫은 경우. Windows는 외부 브라우저를 사용하므로 사용자가 브라우저를 닫은 것을 감지하지 못합니다. | 로그인 화면 유지 |
UnknownOutcome | 이 SDK 버전이 알지 못하는 신규 결과 | 로깅 후 보수적으로 처리 |
Failure | 공통 Failure입니다. 진행 중인 세션이 있어 거부된 경우와 Windows에서 리다이렉트 URI를 먼저 예약하지 않은 경우(FailedPrecondition), 앱이 취소한 경우(Cancelled)도 여기로 분기하며 원인은 Failure.Problem.Code에 담깁니다. 공통 오류 처리를 참조하세요. | 공통 오류 처리 기준에 따라 처리 |
Windows에서는 사용자가 브라우저를 닫아도 OpenAsync()가 끝나지 않고 계속 기다립니다. 로그인 화면에 취소 버튼을 두어 진행 중인 세션 취소를 호출하거나, 취소 토큰으로 제한 시간을 정하세요.
진행 중인 세션 취소
CancelCurrentSession
사용자가 로그인 화면을 벗어나는 등 앱이 먼저 인증을 중단해야 할 때 CancelCurrentSession()을 호출합니다. 진행 중인 세션이 없으면 아무 동작도 하지 않습니다.
취소하면 대기 중이던 OpenAsync()가 Failure로 끝나고 Failure.Problem.Code에 Cancelled가 담깁니다. 사용자가 인증 창을 직접 닫아 발생하는 UserCanceled와는 구분됩니다.