콘텐츠로 이동

로그아웃

현재 로그인한 사용자를 이 기기에서 로그아웃하고 인증 상태를 제거합니다.

LogoutPlayerAsync()는 서버에 로그아웃을 요청할 뿐, 앱 클라이언트의 메모리 세션과 저장된 토큰은 지우지 않습니다. 이미 발급된 액세스 토큰은 로그아웃한 뒤에도 만료될 때까지 유효하므로, 앱이 결과를 보고 메모리 세션과 저장된 토큰을 직접 지워야 합니다. 단, 서버가 로그아웃을 확정한 경우에만 지우세요.

1. 로그아웃 메서드 호출

Method

LogoutPlayerAsync

호출한 기기의 로그인 세션을 서버에서 종료하도록 요청합니다. 같은 계정으로 로그인한 다른 기기의 세션은 유지됩니다.

Warning

게스트 단독 계정은 게스트 외에 다른 로그인 수단을 하나도 연동하지 않은 계정입니다. 게스트 단독 계정은 이후 로그인 수단을 잃는 것을 막기 위해 로그아웃할 수 없습니다. 게스트 단독 계정 로그아웃을 시도하면 GuestSignoutBlocked 응답을 반환합니다. 이 응답을 받으면 활성 세션과 저장된 자격 증명을 유지합니다.

호출 파라미터

필드명 타입 필수 여부 설명
context ApiCallContext Optional 호출 단위 설정 객체입니다. 생략하면 기본값이 사용됩니다.

호출 예시

요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.

using Hive.Axyl.Auth;
using Hive.Axyl.Core;
using UnityEngine;

IAuthService auth = HiveCore.Resolve<IAuthService>();

AuthLogoutPlayerResult result = await auth.LogoutPlayerAsync();

switch (result)
{
    case AuthLogoutPlayerResult.Success:
        // 서버 로그아웃 성공 → 로컬 정리(2~3단계)로 이어집니다.
        break;

    case AuthLogoutPlayerResult.GuestSignoutBlocked:
        // 게스트 단독 계정은 로그아웃할 수 없습니다(로그아웃하면 계정을 다시 사용할 수 없으므로).
        // 정책에 맞춰 사용자에게 안내합니다.
        break;

    // 공통 Failure 처리
    case AuthLogoutPlayerResult.Failure failure:
        HiveError err = failure.Problem;
        Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
        break;

    // 안전망: 처리하지 않은 결과 및 알 수 없는 신규 결과(UnknownOutcome)
    default:
        Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
        break;
}

응답 데이터

성공 시 별도 반환 데이터가 없습니다.

응답 예시

// AuthLogoutPlayerResult.Success는 별도 Data를 반환하지 않습니다.

응답 상태

AuthLogoutPlayerResult의 응답 케이스는 switch 구문으로 처리하는 것을 권장합니다.

Success를 제외한 모든 결과에서는 메모리 세션과 저장된 토큰을 유지하세요. 네트워크 오류나 타임아웃으로 요청이 실패하면 서버가 로그아웃을 처리했는지 알 수 없습니다. 이때 토큰을 지우면 서버에 남아 있는 세션을 다시 끊을 방법이 없어질 수 있으므로, 세션을 유지한 채 로그아웃을 다시 시도하세요.

응답 케이스 설명 앱 클라이언트 대응
Success 서버 로그아웃 요청이 정상 처리됨 아래 2단계와 3단계에서 메모리 세션과 저장 토큰을 삭제합니다. 요청을 취소했더라도 결과가 Success이면 서버가 이미 로그아웃을 처리한 것이므로 삭제합니다.
GuestSignoutBlocked 게스트 단독 계정이 이후 로그인 수단을 잃는 것을 막기 위해 로그아웃할 수 없는 경우 활성 세션과 저장된 자격 증명을 유지하고 로그아웃이 차단되었음을 안내합니다.
PlayerNotFound 계정 정보를 찾을 수 없는 경우 서버와 제품 정책을 확인한 뒤 처리합니다.
AppIdMismatch X-App-Id 헤더의 앱이 현재 토큰의 프로젝트에 속하지 않는 경우 SDK 초기화 시 App ID 설정과 로그인한 계정의 프로젝트를 확인
InvalidGatewayContext 인증 컨텍스트가 없거나 유효하지 않은 경우 세션 활성화로 세션을 등록했는지 확인
AppNotFound 앱 정보를 찾을 수 없는 경우 콘솔의 앱 등록 상태 확인
TerminateService 서비스가 종료된 앱인 경우 서비스 운영 상태 확인
UnknownOutcome 이 SDK 버전이 알지 못하는 신규 결과 세션과 저장 토큰을 유지하고 로깅합니다.
Failure 공통 Failure입니다. 필수 파라미터 누락·형식 오류(invalid_parameter), 필수 필드 누락(missing_field), X-App-Id 헤더 누락(missing_app_id)도 여기로 분기하며 원인은 Failure.Problem.ExternalCode에 담깁니다. 공통 오류 처리를 참조하세요. 세션과 저장 토큰을 유지합니다. 요청을 취소한 경우도 여기에 해당합니다. 네트워크 오류이면 로그아웃을 다시 시도하고, 그 밖의 원인은 공통 오류 처리 기준에 따라 처리합니다.

2. 메모리 세션 삭제

Method

ClearSession

LogoutPlayerAsync() 호출이 성공하면 ISessionManager.ClearSession()을 호출해 앱 클라이언트의 메모리 세션을 초기화합니다. 모든 세션 필드를 기본값으로 되돌리고, 정리 후 OnSessionExpired 이벤트를 발생시킵니다. 활성 세션이 없으면 아무 동작도 하지 않습니다.

호출 파라미터

필드명 타입 필수 여부 설명
없음 - - 파라미터가 없습니다. HiveCore.Resolve<ISessionManager>()로 세션 매니저를 얻어 호출합니다.

호출 예시

using Hive.Axyl.Core;

ISessionManager session = HiveCore.Resolve<ISessionManager>();

session.ClearSession();   // 메모리 세션 초기화 → OnSessionExpired 발생

응답 데이터

성공 시 별도 반환 데이터가 없습니다.

응답 예시

// ClearSession은 반환값이 없습니다(void).
session.ClearSession();

응답 상태

ClearSession()은 결과 객체를 반환하지 않습니다. 활성 세션이 없으면 아무 동작도 하지 않습니다.

3. 저장된 토큰 삭제

Method

DeleteAsync

ISecureStorage.DeleteAsync()를 호출해 보안 저장소에 저장한 항목을 키 단위로 삭제합니다. 저장소 인스턴스는 보안 저장소 모듈 등록에서 AddSecureStorage로 등록한 뒤 HiveCore.TryResolve<ISecureStorage>(out var storage)로 얻습니다. Unity 에디터처럼 보안 저장소가 등록되지 않는 환경에서는 false를 반환하므로, 이때는 지울 항목도 없어 삭제를 건너뜁니다. 자동 로그인을 위해 저장한 토큰은 로그아웃 직후 이 메서드로 삭제합니다.

호출 파라미터

필드명 타입 필수 여부 설명
request SecureStorageDeleteRequest Required 삭제할 항목 요청
cancellationToken CancellationToken Optional 취소 토큰입니다. 생략하면 기본값이 사용됩니다.

SecureStorageDeleteRequest

필드명 타입 필수 여부 설명
Key string Required 삭제할 저장 항목의 키. 앱이 토큰을 저장할 때 정한 값입니다(SDK가 정하지 않음).

호출 예시

using Hive.Axyl.Core;
using Hive.Axyl.Storage;
using UnityEngine;

// 보안 저장소가 없는 환경(에디터 등)에서는 지울 것도 없으므로 건너뜁니다.
if (!HiveCore.TryResolve<ISecureStorage>(out var storage))
{
    return;
}

SecureStorageDeleteResult result =
    await storage.DeleteAsync(new SecureStorageDeleteRequest { Key = "hive.axyl.auth.access_token" });

switch (result)
{
    case SecureStorageDeleteResult.Success:
        // 삭제 완료(해당 키가 없던 경우에도 Success로 처리됩니다).
        break;

    case SecureStorageDeleteResult.AccessDenied:
        // 저장소 접근이 거부됨 — 디바이스 보안 설정/권한을 확인합니다.
        break;

    case SecureStorageDeleteResult.DataCorrupted:
        // 저장 데이터가 손상됨 — 전체 정리(ClearAsync)를 고려합니다.
        break;

    // 안전망: 처리하지 않은 결과 및 알 수 없는 신규 결과(UnknownOutcome)
    default:
        Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
        break;
}

응답 데이터

성공 시 별도 반환 데이터가 없습니다.

응답 예시

// Success 분기 예시
// SecureStorageDeleteResult.Success는 별도 Data를 반환하지 않습니다.

응답 상태

응답 케이스 설명 앱 클라이언트 대응
Success 삭제 완료. 해당 키가 존재하지 않던 경우에도 Success입니다. 다음 키 삭제로 진행합니다.
AccessDenied 저장소 접근이 거부됨 디바이스 보안 설정/권한을 확인합니다.
DataCorrupted 저장 데이터가 손상됨 전체 정리(ClearAsync)를 고려합니다.
Failure 공통 Failure입니다. 공통 오류 처리를 참조하세요. 공통 오류 처리 기준에 따라 처리
UnknownOutcome 알 수 없는 신규 결과 안전망으로 로깅 후 보수적으로 처리합니다.

전체 흐름 예시

로그아웃, 메모리 세션 삭제, 저장된 토큰 삭제를 순서대로 처리하는 예시 코드입니다. 로그아웃이 성공한 경우에만 메모리 세션과 저장 토큰을 함께 정리합니다.

Note

이 예시는 HiveCore.TryResolve<ISecureStorage>(out var storage)로 보안 저장소를 가져옵니다. Unity 에디터에서는 보안 저장소가 등록되지 않아 HiveCore.Resolve<ISecureStorage>()가 RegistrationNotFoundException을 발생시키기 때문입니다. 지원 범위는 보안 저장소 모듈 등록을 참조하세요.

using Hive.Axyl.Auth;
using Hive.Axyl.Core;
using Hive.Axyl.Storage;
using System.Threading;
using System.Threading.Tasks;

public class LogoutFlow
{
    private readonly IAuthService _auth = HiveCore.Resolve<IAuthService>();
    private readonly ISessionManager _session = HiveCore.Resolve<ISessionManager>();

    public async Task<bool> SignOutAsync(CancellationToken ct = default)
    {
        var result = await _auth.LogoutPlayerAsync(new ApiCallContext { Token = ct });

        // 성공이 아닌 경우(실패·취소·GuestSignoutBlocked 등)는 세션을 유지하고
        // 재시도/안내 정책을 따릅니다.
        if (result is not AuthLogoutPlayerResult.Success)
        {
            return false;
        }

        // 서버가 로그아웃을 확정했으므로, 그사이 취소됐더라도 끝까지 정리합니다.
        _session.ClearSession();   // 메모리 세션 제거 → OnSessionExpired 발생
        await DeleteStoredTokensAsync(CancellationToken.None);
        return true;
    }

    private async Task DeleteStoredTokensAsync(CancellationToken ct)
    {
        // 보안 저장소가 없는 환경(에디터 등)에서는 지울 것도 없으므로 건너뜁니다.
        if (!HiveCore.TryResolve<ISecureStorage>(out var storage))
        {
            return;
        }

        // 아래 키는 앱이 토큰을 저장할 때 정한 값의 예시입니다(SDK가 정하지 않음).
        await storage.DeleteAsync(new SecureStorageDeleteRequest { Key = "hive.axyl.auth.access_token" }, ct);
        await storage.DeleteAsync(new SecureStorageDeleteRequest { Key = "hive.axyl.auth.refresh_token" }, ct);
        await storage.DeleteAsync(new SecureStorageDeleteRequest { Key = "hive.axyl.auth.player_id" }, ct);
        await storage.DeleteAsync(new SecureStorageDeleteRequest { Key = "hive.axyl.auth.expires_at" }, ct);
        await storage.DeleteAsync(new SecureStorageDeleteRequest { Key = "hive.axyl.auth.guest_token" }, ct);
        await storage.DeleteAsync(new SecureStorageDeleteRequest { Key = "hive.axyl.auth.guest_player_id" }, ct);
    }
}

이 예제는 HiveCore.TryResolve<ISecureStorage>(out var storage)로 가져온 저장소를 사용합니다. 로그아웃이 성공하면 ClearSession()을 호출한 직후 저장한 토큰 키를 명시적으로 삭제합니다. 서버가 로그아웃을 확정한 뒤에는 토큰 삭제에 취소 토큰을 넘기지 않으므로, 그사이 취소가 요청돼도 저장한 토큰이 남지 않습니다.

저장 항목과 로그아웃 시 처리 기준

ISessionManager는 메모리 세션만 관리합니다. 게스트 계정은 로그아웃 이후 재사용할 수 없으므로, 로그아웃 시에는 메모리 세션 정리와 저장소 정리를 분리하지 않고 함께 처리해야 합니다.

저장 항목 목적 로그아웃 시 권장 처리
accessToken, refreshToken, playerId, expiresAtSec 자동 로그인 세션 복구 로그아웃 직후 삭제합니다.
deviceKey 기기 식별 유지합니다.
guestToken, guestPlayerId 게스트 세션 식별 로그아웃 직후 삭제합니다.

구현 체크리스트

  • 로그아웃 호출 전 활성 세션 존재 여부를 확인
  • 로그아웃 성공 여부를 확인한 뒤에만 메모리 세션과 저장 토큰을 정리
  • 네트워크 오류로 로그아웃이 실패하면 메모리 세션과 저장 토큰을 유지하고 로그아웃을 다시 시도
  • 로그아웃 이후 메모리 세션과 저장 토큰 정리 정책을 분리하지 않고 일관되게 적용
  • 자동 로그인 기능을 사용하는 경우, 로그아웃 직후 저장 토큰이 남지 않도록 검증
  • guestToken, guestPlayerId가 로그아웃 직후 삭제되는지 검증