로그아웃 구현하기
레시피 코드로 로그아웃을 구현하려면 아래 절차를 순서대로 완료하세요.
시작하기 전에 공통 사전 준비를 마치세요.
전체 흐름
각 단계에서 무엇을 설정하고 무엇을 호출하는지는 아래와 같습니다.
| 순서 | 구분 | 하는 일 |
|---|---|---|
| 1 | Hive Axyl SDK | 인증 모듈과 보안 저장소 모듈 설치 |
| 2 | Hive Axyl SDK | SDK 초기화와 모듈 등록 |
| 3 | 레시피 코드 | 레시피 폴더 복사 |
| 4 | 앱 코드 | 로그아웃 버튼과 취소 처리 연결 |
| 5 | 레시피 코드 | 로그아웃 호출 |
| 6 | 앱 코드 | 결과와 저장 정보 처리 |
| 7 | Hive Axyl SDK, 앱 코드 | 기기에 저장한 토큰 삭제 |
| 8 | 앱 코드 | 동작 확인 |
저장 정보 삭제와 화면 이동은 SessionCleared를 기준으로 처리하세요
Status는 요청이 끝난 형태만 알려 줍니다. 현재 기기의 로그인 세션이 실제로 지워졌는지는 SessionCleared가 알려 주므로, 두 값을 같은 의미로 다루면 안 됩니다.
1. SDK 모듈 설치
-
Hive Axyl SDK Hive Axyl SDK를 앱에서 호출합니다.
상세 절차: 모듈 설치
인증 모듈과 보안 저장소 모듈을 Unity 프로젝트에 설치하세요. 보안 저장소 모듈은 로그아웃 뒤에 기기에 저장한 토큰을 지울 때 사용합니다.
| 패키지 | 필요 여부 | 역할 |
|---|---|---|
com.com2usplatform.hiveaxyl.core | 필수 | SDK 초기화와 현재 로그인 세션 관리 |
com.com2usplatform.hiveaxyl.auth | 필수 | 로그아웃 요청 |
com.com2usplatform.hiveaxyl.storage | 권장 | 자동 로그인에 사용한 토큰의 삭제 |
앱에서 이미 안전한 저장소를 사용한다면 com.com2usplatform.hiveaxyl.storage를 설치하지 않아도 됩니다. 이 경우에도 자동 로그인에 사용한 정보를 로그아웃 직후에 지울 수 있어야 합니다.
2. SDK 초기화
-
Hive Axyl SDK Hive Axyl SDK를 앱에서 호출합니다.
상세 절차: SDK 초기화, 보안 저장소 모듈 등록
앱 시작 지점에서 SDK를 한 번 초기화하고 인증 모듈과 보안 저장소 모듈을 등록하세요. 레시피는 SDK를 초기화하지 않으므로, 초기화하지 않은 상태에서 호출하면 FailedPrecondition 오류로 실패합니다.
아래는 로그아웃에 필요한 모듈을 등록해 초기화하는 예제 코드입니다.
{appId}에는 Hive 콘솔에서 만든 App ID를 입력하세요.
AddAuth()를 등록하지 않으면 레시피가 FailedPrecondition 오류로 실패합니다. 위 예제의 AddToken()은 로그아웃 레시피가 사용하지 않지만, 로그인에 필요하므로 함께 등록해 둡니다. 로그인 단계에서 이미 초기화를 마쳤다면 다시 호출하지 마세요.
3. 레시피 코드 설치
- 레시피 코드 레시피 코드를 프로젝트에 복사합니다.
레시피는 패키지가 아니라 프로젝트에 복사해서 사용하는 소스 코드입니다. axyl-samples-unity 저장소에서 아래 항목을 Unity 프로젝트의 Assets/Recipes/ 아래로 복사하세요.
복사할 항목과 역할은 아래와 같습니다.
- Recipes.asmdef: 레시피 공통 어셈블리 정의
- AssemblyInfo.cs: 내부 헬퍼를 다른 레시피 어셈블리에 공개하는 설정
- Helper/: 여러 레시피가 함께 사용하는 공통 코드
- Logout/:
LogoutRecipe와 결과 유형
앱 코드에서 레시피를 호출하려면 앱 쪽 어셈블리 정의의 references에 아래 어셈블리를 추가하세요. 원본 Recipes.asmdef의 autoReferenced 값이 false이므로 앱 어셈블리가 자동으로 참조하지 않습니다.
MyApp은 앱에서 사용하는 어셈블리 이름으로 바꾸고, 기존 설정과 참조는 유지하세요. Unity 어셈블리는 참조를 전이하지 않으므로 앱 코드가 직접 사용하는 어셈블리를 모두 여기에 적어야 합니다. Hive.Axyl.Core에는 CoreConfig와 HiveError가, Hive.Axyl.Auth에는 AddAuth()와 AddToken()이, Hive.Axyl.Storage에는 AddSecureStorage()가 들어 있습니다. AddSecureStorage()를 등록하지 않는다면 Hive.Axyl.Storage는 적지 않아도 됩니다.
Logout/만 복사하면 컴파일되지 않습니다
LogoutRecipe는 Helper/의 결과 분류 코드를 사용합니다. Helper/, Recipes.asmdef, AssemblyInfo.cs를 함께 복사하세요.
4. 로그아웃 버튼과 취소 처리 연결
- 앱 코드 앱에서 직접 구현합니다.
로그아웃 버튼을 선택했을 때 중복 요청이 발생하지 않도록 버튼을 잠그고, 화면을 닫을 때 기다리기를 멈출 수 있도록 취소 토큰을 준비하세요.
LogoutRecipe는 생성자 인자를 받지 않습니다. 화면 컴포넌트에서 한 번 만들어 재사용하세요.
5. 로그아웃 호출
- 레시피 코드 레시피 코드를 앱에서 호출합니다.
버튼을 선택하면 LogoutAsync()를 호출하세요. 레시피가 서버에 로그아웃을 요청하고, 요청이 성공하면 현재 기기의 메모리 세션까지 정리합니다.
var cancellation = new CancellationTokenSource();
m_logoutCancellation = cancellation;
try
{
SetLogoutButtonEnabled(false);
// 7단계에서 이 계정의 저장 정보만 지울 수 있도록 로그아웃할 계정을 기억해 둡니다.
long playerId = HiveCore.Resolve<ISessionManager>().PlayerId;
LogoutOutcome outcome = await m_logoutRecipe.LogoutAsync(cancellation.Token);
WriteLogoutLog(outcome);
await HandleLogoutOutcomeAsync(outcome, playerId);
}
finally
{
cancellation.Dispose();
m_logoutCancellation = null;
SetLogoutButtonEnabled(true);
}
SetLogoutButtonEnabled, WriteLogoutLog, HandleLogoutOutcomeAsync는 앱이 구현하는 메서드입니다. 결과 처리 내용은 6단계에서 이어집니다.
레시피가 내부에서 수행하는 작업은 아래와 같습니다.
| 구분 | 호출 | 확인할 곳 |
|---|---|---|
| Hive Axyl SDK | LogoutPlayerAsync()로 서버에 로그아웃 요청 | 로그아웃 메서드 호출 |
| Hive Axyl SDK | ClearSession()으로 메모리 세션 정리 | 메모리 세션 삭제 |
레시피는 요청을 보내기 전에 인증 기능과 세션 관리 기능이 등록되어 있는지, 그리고 종료할 로그인 세션이 있는지를 먼저 확인합니다. 하나라도 준비되지 않으면 서버를 호출하지 않고 FailedPrecondition 오류를 반환합니다.
레시피는 로그아웃을 요청하기 전의 액세스 토큰을 기억해 두었다가, 응답이 돌아왔을 때 세션이 그대로인 경우에만 ClearSession()을 호출합니다. 요청을 기다리는 동안 다시 로그인해 새 세션이 들어왔다면 그 세션은 지우지 않습니다.
기기에 저장한 토큰은 레시피가 지우지 않습니다. 삭제는 7단계에서 앱이 직접 처리합니다.
6. 결과와 저장 정보 처리
-
앱 코드 앱에서 직접 구현합니다.
상세 절차: 로그아웃 메서드 호출, HiveError 정보
SessionCleared가 true일 때만 저장 정보를 삭제하고 로그인 화면으로 이동하세요. Status만 보고 분기하면 세션이 남아 있는 상태에서 저장 정보를 잃게 됩니다.
LogoutOutcome의 Status는 Success, BusinessOutcome, Failure 세 가지입니다. BusinessOutcome 속성은 Status가 BusinessOutcome일 때만 의미가 있습니다. 서버가 돌려주는 거절 사유에는 GuestSignoutBlocked 외에도 서비스 종료, 앱 정보 불일치, 계정 조회 실패 등이 있으므로, 전체 목록은 위 상세 절차에서 확인하세요.
| 조건 | 현재 상태 | 앱 처리 |
|---|---|---|
SessionCleared == true | 현재 기기의 로그인 세션이 지워짐 | 저장한 자동 로그인 정보를 삭제한 뒤 로그인 화면으로 이동합니다. |
SessionCleared == false 및 Status == Success | 요청 중에 다시 로그인했거나 토큰이 갱신되어 세션이 바뀜 | 화면을 이동하지 않습니다. ISessionManager가 가지고 있는 현재 세션 값으로 저장 정보를 갱신합니다. |
SessionCleared == false 및 BusinessOutcome == GuestSignoutBlocked | 게스트 계정의 로그인 세션 유지 | 저장 정보를 유지하고 게스트 계정은 로그아웃할 수 없음을 안내합니다. |
SessionCleared == false 및 Status == Failure | 로그인 세션 유지 | 저장 정보를 유지하고 오류 안내 또는 재시도 화면을 표시합니다. |
SessionCleared == false 및 나머지 거절 사유 | 로그인 세션 유지 | 저장 정보를 유지하고 거절 사유에 맞는 안내를 표시합니다. |
게스트 계정은 로그아웃할 수 없습니다
다른 로그인 수단을 하나도 연동하지 않은 게스트 계정은 로그아웃하면 다시 로그인할 수단을 잃습니다. 그래서 서버가 로그아웃을 거절하고 GuestSignoutBlocked를 반환합니다. 오류가 아니라 정책이므로, 게스트 계정에도 로그아웃 버튼을 제공한다면 이 결과를 반드시 처리하세요.
취소 토큰을 취소하면 Status는 Failure가 되고 Error.Code는 HiveErrorCode.Cancelled가 됩니다. 이때도 서버가 이미 세션을 종료했고 그사이 세션이 바뀌지 않았다면 SessionCleared가 true로 돌아오므로, 취소 결과에서도 SessionCleared를 확인하세요.
Error, FailedStep, UnknownOutcomeCode, RawJson은 앱 로그와 진단에만 사용하세요. 사용자에게는 앱에서 정한 이해하기 쉬운 메시지를 표시하고, 토큰은 기록하지 마세요.
7. 기기에 저장한 토큰 삭제
-
Hive Axyl SDK Hive Axyl SDK를 앱에서 호출합니다.
앱 코드 앱에서 직접 구현합니다.
상세 절차: 저장된 토큰 삭제
SessionCleared가 true이면 자동 로그인에 사용한 토큰을 기기에서 지우세요. 레시피는 메모리 세션만 정리하므로, 이 값을 남겨 두면 다음 실행에서 로그아웃한 계정으로 다시 로그인됩니다.
7.1. 삭제할 정보
지울 값은 로그아웃한 계정의 자동 로그인 정보뿐입니다. 5단계에서 기억해 둔 PlayerId와 저장한 자동 로그인 정보의 PlayerId가 같을 때만 지우세요.
저장 항목별 처리는 아래와 같습니다.
- 로그아웃한 계정의 자동 로그인 정보: 삭제
DeviceKey: 유지. 계정이 아니라 기기 단위로 로그인 세션을 구분하는 값- 게스트 자격 증명: 유지. 지우면 그 게스트 계정에 다시 로그인할 수 없음
7.2. 삭제 방법과 실패 처리
com.com2usplatform.hiveaxyl.storage를 사용하는 앱은 ISecureStorage.DeleteAsync()로 저장 항목을 키 단위로 삭제합니다. 앱이 직접 준비한 저장소를 쓴다면 그 저장소의 삭제 방식을 그대로 사용하세요.
삭제에 실패하면 로그인 화면에서 재시도를 안내하세요. 삭제가 끝나지 않은 상태로 자동 로그인을 실행하면 사용자가 의도하지 않은 계정으로 다시 들어갑니다.
8. 동작 확인
- 앱 코드 앱에서 동작을 확인합니다.
일반 계정, 게스트 계정, 통신 실패, 취소 상황에서 로그아웃 동작을 확인하세요.
상황별로 확인할 결과는 아래와 같습니다.
- 일반 로그인 계정에서 로그아웃:
SessionCleared가true이고 저장한 자동 로그인 정보가 삭제된 뒤 로그인 화면으로 이동 - 게스트 계정에서 로그아웃:
GuestSignoutBlocked와SessionCleared == false를 확인하고 현재 화면과 저장 정보를 유지 - 로그아웃 중 통신 실패:
SessionCleared == false를 확인하고 현재 세션을 유지한 채 재시도 화면 표시 - 로그아웃 요청 취소:
Status와 관계없이SessionCleared를 기준으로 저장 정보와 화면을 처리
다음 단계
사용자가 계정 자체를 지우는 흐름까지 제공하려면 계정 삭제를 참조하세요.