콘텐츠로 이동

Hive Axyl SDK 오류 처리

Hive Axyl SDK 호출이 실패했을 때 원인을 확인하고 대응하는 방법입니다. 결과를 분기하는 순서, Failure의 원인을 담은 HiveError 확인, 모듈마다 다른 공통 Failure 코드, Add-on 결과 처리, 예외, 그리고 실패 상황에서 저장된 인증 정보를 어떻게 다뤄야 하는지를 다룹니다.

타입의 속성과 값 목록은 Core 오류와 Core 결과 모델에 있습니다. 이 페이지는 그 값을 실제로 어떻게 처리할지에 집중합니다.

메서드 결과

Hive Axyl 서버를 호출하는 메서드는 아래 네 갈래 중 하나의 결과 객체를 반환합니다. 결과 갈래를 구분하는 방법은 Core 결과 모델을 참조하세요.

갈래 반환되는 경우 처리
Success 서버가 요청을 처리했고 응답 데이터를 해석했습니다. Data의 응답 데이터를 사용합니다.
메서드별 Outcome 서버가 이 메서드에 정의된 결과 코드로 응답했습니다. 결과마다 사용자 안내나 대체 흐름을 제공합니다.
UnknownOutcome 서버가 보낸 결과 코드를 이 SDK 버전이 알지 못합니다. 알 수 없는 결과를 참조하세요.
Failure 네트워크 단절이나 호출 취소처럼 호출을 마치지 못했거나, 서버가 기능 관점의 결과가 아닌 오류로 응답했습니다. Failure.Problem의 HiveError로 원인을 확인합니다.

switch 구문에서는 Success, 앱이 대응할 Outcome, Failure 순으로 분기하세요. UnknownOutcome은 Code와 RawJson을 기록해야 하므로 별도 case로 분기해 실패로 처리하고, 앱이 따로 대응하지 않는 나머지 Outcome은 default에서 처리하세요. ApiCallContext로 취소 토큰을 넘겨 호출을 취소할 수 있게 했다면, Failure를 일반 오류로 처리하기 전에 HiveErrorCode.Cancelled인지 먼저 확인하세요.

HiveError 정보

Failure의 원인은 Failure.Problem에 담긴 HiveError로 확인합니다. 원인을 구분할 때는 아래 속성을 사용하며, 전체 속성과 Code에 들어갈 수 있는 값은 Core 오류를 참조하세요.

  • Code: 실패 원인을 분류한 HiveErrorCode 값
  • ExternalCode: 서버나 플랫폼이 보낸 원래 오류 코드. 서버가 보낸 공통 Failure 코드, HTTP 500처럼 HTTP 상태를 나타내는 값, Net_Offline 같은 네트워크 오류 구분 값이 담깁니다.
  • Message: 원인을 파악하기 위한 영어 진단 메시지
  • Type, Instance: 서버가 오류 응답에 담아 보낸 오류 유형 URI와 요청 경로

같은 Code라도 ExternalCode에 따라 원인과 대응이 달라지므로 두 값을 함께 확인하고, 오류를 기록할 때도 함께 남기세요.

실패 원인별 처리

상황 Code ExternalCode 처리
기기가 네트워크에 연결되어 있지 않습니다. Unavailable Net_Offline SDK는 이 실패를 재시도하지 않습니다. 사용자에게 네트워크 연결을 확인하도록 안내하세요.
서버에 연결하지 못했거나 요청 제한 시간이 지났습니다. Unavailable Net_ConnectionError 잠시 후 다시 시도하세요. 멱등 요청은 SDK가 먼저 자동으로 재시도합니다.
요청 빈도가 허용 한도를 넘었습니다. ResourceExhausted Net_RateLimited 또는 서버가 보낸 공통 Failure 코드 SDK가 자동 재시도를 마쳤거나, 서버가 요구한 대기 시간이 최대 대기 시간을 넘어 재시도하지 않은 상태입니다. 시간을 두고 다시 시도하세요.
호출을 취소했습니다. Cancelled - 결과를 처리하지 마세요. 서버에 이미 전달된 요청까지 취소된다는 보장은 없습니다.
서버가 공통 Failure 코드로 응답했습니다. HTTP 상태 코드로 정해집니다. 서버가 보낸 공통 Failure 코드 모듈별 공통 Failure 코드를 참조하세요.
서버가 오류 코드 없이 오류로 응답했습니다. HTTP 상태 코드로 정해집니다. HTTP 500처럼 HTTP와 상태 코드를 이은 값 HTTP 상태 코드와 HiveErrorCode를 참조하세요.
서버의 성공 응답을 해석하지 못했습니다. Internal - Code, Message, 결과의 RawResponse를 기록하세요.
인증 정보로 빈 액세스 토큰을 지정했습니다. InvalidArgument - ApiCallContext.WithAccessToken()에 넣은 토큰 값을 확인하세요.

HTTP 상태 코드와 HiveErrorCode

서버가 오류 코드 없이 응답했거나 공통 Failure 코드로 응답하면 Code는 응답의 HTTP 상태 코드에 따라 아래와 같이 정해집니다.

  • 400, 422: InvalidArgument
  • 401: Unauthenticated
  • 403: PermissionDenied
  • 404: NotFound
  • 409: AlreadyExists
  • 429: ResourceExhausted
  • 500: Internal
  • 501: Unimplemented
  • 502, 503: Unavailable
  • 504: DeadlineExceeded
  • 그 밖의 4xx: Unknown
  • 그 밖의 상태 코드: Internal

자동 재시도

SDK는 일시적인 실패로 판단한 요청을 앱에 결과를 돌려주기 전에 자동으로 다시 보냅니다. 앱이 받는 Failure는 자동 재시도를 모두 마친 뒤의 결과입니다.

재시도 횟수와 제한 시간의 기본값은 Core 설정에서, 호출 하나에만 적용할 값은 Core 호출 컨텍스트에서 지정합니다. 실패 유형별 자동 재시도 여부는 아래와 같습니다.

HTTP 상태 코드 429

HTTP 상태 코드 429를 받으면 SDK는 항상 재시도합니다. 서버가 Retry-After 헤더를 보내면 그만큼 기다리며, 대기 시간이 설정한 최대 대기 시간을 넘으면 기다리지 않고 ResourceExhausted로 실패합니다.

서버 오류와 서버 연결 실패

HTTP 상태 코드 500, 502, 503, 504를 받거나 서버에 연결하지 못하면 멱등 요청만 재시도합니다. 멱등 요청은 HTTP 메서드가 GET, PUT, DELETE, HEAD, OPTIONS인 요청과, 호출 단위로 IsIdempotent를 true로 지정한 요청입니다.

재시도하지 않는 실패

네트워크에 연결되어 있지 않거나, 앞에서 설명하지 않은 상태 코드를 받으면 재시도하지 않습니다. 429를 제외한 4xx와 501, 505 같은 상태 코드가 여기에 해당합니다.

토큰 자동 갱신 실패

로그인 세션으로 호출하는 메서드는 액세스 토큰이 더 이상 받아들여지지 않아 서버가 401로 응답하면 SDK가 토큰을 갱신한 뒤 요청을 다시 보냅니다. 앱은 다시 보낸 요청의 결과를 받습니다. 앱이 ApiCallContext.WithAccessToken()으로 직접 지정한 토큰으로 호출한 요청은 자동 갱신 대상이 아닙니다. 자동 갱신은 AuthTokenRefresh.Enable()로 갱신 처리를 등록했고, 자동 갱신 설정이 켜져 있으며, 세션에 리프레시 토큰이 있을 때만 동작합니다.

갱신이 실패하면 아래와 같이 결과가 달라집니다.

갱신 결과 호출 결과 처리
서버가 리프레시 토큰을 무효로 판정 Unauthenticated 세션이 정리되고 OnSessionExpired가 발생합니다. 저장한 인증 정보를 지우고 사용자가 다시 로그인하도록 안내하세요.
네트워크나 서버 오류로 판정을 받지 못함 Unavailable 세션은 그대로 유지됩니다. 잠시 후 다시 호출하세요.
다른 호출이 진행하던 갱신이 취소됨 Unavailable, ExternalCode는 Auth_RefreshCancelled 세션은 그대로 유지됩니다. 같은 호출을 다시 시도하세요.
판정을 받지 못한 갱신이 세 번 연속 실패해 갱신이 중단됨 Unavailable, ExternalCode는 Auth_RefreshHalted 재시도로는 복구되지 않습니다. IsLoggedIn을 확인한 뒤 다시 로그인하거나 저장한 인증 정보로 세션을 복원하세요. 저장한 인증 정보는 지우지 마세요.
갱신을 기다리는 요청이 한도를 넘어 대기열에 들어가지 못함 ResourceExhausted 갱신이 끝난 뒤 같은 호출을 다시 시도하세요. 동시에 보내는 호출 수를 줄이면 이 실패가 줄어듭니다.

갱신에 성공한 뒤 다시 보낸 요청이 또 401을 받으면 SDK는 갱신을 되풀이하지 않고 Unauthenticated Failure로 반환합니다. 갱신에 성공하면 OnSessionRefreshed가 발생합니다. 리프레시 토큰은 갱신할 때마다 새 값으로 바뀌므로, 저장해 둔 인증 정보는 이 이벤트에서 갱신하세요.

모듈별 공통 Failure 코드

서버가 오류 코드로 응답해도, 요청 형식이나 인증 상태처럼 기능 관점의 결과가 아닌 공통 코드는 Outcome이 아닌 Failure로 반환됩니다. 이때 서버가 보낸 코드는 Failure.Problem.ExternalCode에 담기고, Code는 응답의 HTTP 상태 코드로 정해집니다. 공통 Failure 코드의 목록은 모듈마다 다르므로 호출한 모듈의 목록을 확인하세요.

계정 및 인증

IAuthService와 ITokenService의 메서드는 아래 세 코드를 Failure로 반환합니다. 코드 목록은 레퍼런스 공통 규약에도 정리되어 있습니다.

  • invalid_parameter: 형식에 맞지 않는 요청 파라미터
  • missing_field: X-App-Id 헤더를 보내지 않은 경우처럼 필수 필드나 필수 헤더 자체가 누락된 경우
  • missing_app_id: X-App-Id 헤더는 보냈지만 값이 비어 있는 경우

결제, 우편함, 푸시 알림, 쿠폰, 분석 로그

IPaymentsService, IMailboxService, IPushService, ICouponService, IAnalyticsService의 메서드는 아래 14개 코드를 Failure로 반환합니다. 모듈별 목록은 IPaymentsService, IMailboxService, IPushService, ICouponService, IAnalyticsService에도 정리되어 있습니다.

  • bad_request: 잘못된 요청
  • invalid_parameter: 형식에 맞지 않는 요청 파라미터
  • missing_field: X-App-Id 헤더를 보내지 않은 경우처럼 필수 필드나 필수 헤더 자체가 누락된 경우
  • missing_app_id: X-App-Id 헤더는 보냈지만 값이 비어 있는 경우
  • unauthorized: 인증 토큰이 없거나 유효하지 않은 경우
  • token_expired: 인증 토큰 만료
  • forbidden: 요청 권한 없음
  • resource_not_found: 요청한 리소스 없음
  • method_not_allowed: 허용되지 않은 요청 방식
  • resource_conflict: 요청과 리소스 상태의 충돌
  • unprocessable_content: 처리할 수 없는 요청 내용
  • rate_limit_exceeded: 허용 한도를 넘은 요청 빈도
  • internal_error: 서버 내부 오류
  • service_unavailable: 서비스 일시 중단

payment_bad_request나 resource_not_in_scope처럼 이름이 비슷해도 메서드별로 정의된 코드는 공통 Failure 코드가 아니라 Outcome으로 반환됩니다. 메서드별 Outcome은 각 메서드 레퍼런스의 응답 상태에서 확인하세요.

서비스 접근 제어

IServiceAccessService의 메서드는 아래 두 코드를 Failure로 반환합니다. 코드 목록은 IServiceAccessService에도 정리되어 있습니다.

  • invalid_parameter: 형식에 맞지 않는 요청 파라미터
  • missing_field: 필수 파라미터나 필수 헤더 자체가 누락된 경우

서버가 internal_error 코드로 응답한 내부 오류는 이 모듈에서 Failure가 아니라 UnknownOutcome으로 분기하며, 코드는 UnknownOutcome.Code에 담깁니다.

TCB Connector

ITcbService는 공통 Failure 코드를 선언하지 않습니다. 다른 모듈이 공통 Failure 코드로 반환하는 invalid_parameter도 이 모듈에서는 결과 케이스입니다.

ITcbService의 메서드는 전송 실패, 호출 취소, 오류 코드 없이 응답한 서버 내부 오류를 Failure로 반환하고, 결과 케이스에 없는 코드로 서버가 응답하면 UnknownOutcome으로 반환합니다. 자세한 내용은 ITcbService의 실패 분기를 참조하세요.

알 수 없는 결과

서버가 보낸 결과 코드를 이 SDK 버전이 알지 못하면 UnknownOutcome이 반환됩니다. SDK를 배포한 뒤 서버에 새 결과 코드가 추가된 경우와, 메서드에 정의되지 않은 코드로 서버가 응답한 경우가 여기에 해당합니다. UnknownOutcome에는 아래 두 속성이 담깁니다.

  • Code: 서버가 보낸 결과 코드
  • RawJson: 서버가 보낸 응답 본문 원문

UnknownOutcome은 실패로 처리하세요. Code와 RawJson을 기록하고 사용자에게는 일반적인 실패 안내를 보여 주세요. 결과가 확정되지 않은 상태이므로 이 결과를 근거로 저장된 인증 정보나 세션을 삭제하지 마세요.

Add-on 결과

Add-on은 스토어나 운영 체제의 기능을 감싸므로, 서버 API 모듈과 다른 상황에서 결과가 갈립니다. 상황별 결과는 아래와 같습니다.

  • 지원하지 않는 플랫폼: Add-on이 등록되지 않아 HiveCore.Resolve<T>()에서 예외 발생. HiveCore.TryResolve<T>()로 등록 여부를 먼저 확인하세요.
  • SDK를 초기화하기 전의 호출: Code가 FailedPrecondition인 Failure
  • 사용자가 운영 체제 화면에서 취소: UserCanceled 같은 메서드별 Outcome
  • 앱이 취소 토큰이나 세션 취소 메서드로 취소: Code가 Cancelled인 Failure
  • 스토어나 운영 체제의 오류 반환: 스토어가 보낸 오류 코드를 ExternalCode에 담은 Failure. 예를 들어 Google Play Billing은 BillingResponse:ITEM_ALREADY_OWNED 형식으로 담깁니다.

Add-on 메서드는 ApiCallContext 대신 CancellationToken을 받습니다. 결제 Add-on 외에 계정 및 인증, 푸시 알림 Add-on도 같은 방식으로 결과가 갈립니다. 메서드별 결과와 이벤트는 Hive Axyl SDK 레퍼런스의 모듈 표에서 해당 Add-on 레퍼런스를 찾아 참조하세요.

결제 Add-on

결제 Add-on은 결제 결과의 일부를 메서드 결과가 아니라 이벤트로 전달하므로, 메서드 결과와 이벤트를 함께 처리해야 결제 흐름이 끊기지 않습니다. 결제 Add-on별로 결과를 확인하는 방법은 아래와 같습니다.

Apple StoreKit

Apple StoreKit Add-on의 PurchaseAsync() 결과는 성공, 사용자가 결제 화면을 닫은 UserCanceled, 승인 대기 상태인 Pending, UnknownOutcome, Failure로 나뉩니다. Pending을 받은 결제의 최종 결과는 나중에 TransactionUpdated 이벤트로 전달되며, 이 이벤트는 거래 옵저버를 시작해 둔 동안에만 받습니다.

성공 결과에도 서명 검증을 통과하지 못한 거래가 담길 수 있으므로, 앱 서버에서 Hive Axyl Server API로 영수증을 검증하세요. 검증 흐름은 영수증 검증을 참조하세요.

Google Play Billing

Google Play Billing Add-on에서 LaunchBillingFlowAsync()의 성공은 결제 화면을 띄웠다는 뜻입니다. 실제 구매 결과는 PurchasesUpdated 이벤트의 BillingResult.ResponseCode와 구매 목록에서 확인합니다. 사용자가 결제를 취소하면 이벤트의 응답 코드가 취소를 나타내고 구매 목록은 비어 있습니다.

연결이 끊기면 BillingServiceDisconnected 이벤트가 발생합니다. SDK는 다시 연결하지 않으므로 앱에서 연결을 다시 시작하세요.

Steam Microtransactions

Steam Microtransactions Add-on은 결제 승인 결과를 MicroTxnAuthorizationResponse 이벤트로 전달합니다. 이 이벤트는 콜백 리스너가 수신하는 동안에만 발생하므로, 이벤트를 먼저 구독한 뒤 콜백 리스너를 시작하세요. 이벤트의 Authorized가 true이면 사용자가 결제를 승인한 상태이고, false이면 취소한 상태입니다.

Steam 오버레이에서 결제가 실패하면 이벤트가 발생하지 않으므로, 앱 서버에서 주문마다 대기 시간을 정해 두고 처리하세요.

결제 레시피의 거절 사유

결제 활용 가이드의 레시피는 결제 한 건을 처리하면서 Hive Axyl 서버와 마켓을 여러 번 호출합니다. 그중 하나가 요청을 거절하면 레시피 결과의 Status가 BusinessOutcome이 되고, 거절 사유는 어느 호출에서 나왔든 PurchaseBusinessOutcome 값 하나로 전달됩니다. 값은 마이너 릴리스에서 늘어날 수 있으므로 switch에는 default 분기를 두세요.

값 의미 처리
Unrecognized 레시피가 이름을 붙이지 않은 결과입니다. 아래 Unrecognized 설명을 참조하세요.
PaymentBadRequest 서버가 요청 형식을 거절했습니다. 레시피에 넘긴 값을 확인하세요. 같은 값으로 다시 호출하면 결과가 같습니다.
PaymentInvalidParameter 요청 필드 하나가 유효하지 않습니다. 레시피에 넘긴 값을 확인하세요. 같은 값으로 다시 호출하면 결과가 같습니다.
PaymentResourceNotFound 호출이 지정한 주문, 상품, 영수증이 서버에 없습니다. 상품 ID와 주문 정보가 같은 구매의 값인지 확인하세요.
PaymentResourceConflict 저장하려는 기록이 이미 있습니다. 앞선 실행이 같은 구독을 저장한 경우입니다. 실패가 아니므로 앱 서버의 영수증 검증 결과에 따라 흐름을 이어 가세요.
PaymentUnauthorized 사용할 수 있는 로그인 세션 없이 호출했습니다. 로그인 상태를 확인한 뒤 다시 시도하세요.
VerifyError 마켓이 영수증을 거절했습니다. 대금은 이미 청구되었을 수 있습니다. 상품을 지급하지 말고 PendingPurchase를 보관한 뒤 서버가 보낸 메시지를 기록하세요.
StorePurchasePending 마켓이 아직 대금을 받지 않았습니다. Google Play의 충전 대기 구매나 Apple의 Ask to Buy 승인 대기가 여기에 해당합니다. 상품을 지급하지 마세요. 결제가 끝나면 마켓이 구매를 다시 전달합니다.
StoreItemAlreadyOwned 마켓이 사용자가 이미 상품을 보유하고 있다고 응답했습니다. 소모성 상품이면 앞선 구매를 소비하지 않은 상태입니다. 다시 구매하지 말고 남아 있는 구매를 먼저 종료하세요.
NothingToRestore 종료할 미소비 주문이 서버에 없습니다. 사용자가 결제를 마치지 않았거나 이미 소비된 주문입니다. 사용자가 결제를 마친 뒤 같은 호출을 다시 시도하세요.

StorePurchasePending, StoreItemAlreadyOwned, NothingToRestore는 서버가 보낸 코드가 아니라 마켓의 응답이나 레시피의 판단입니다. 나머지 값은 서버가 보낸 결제 오류 코드를 옮긴 값입니다.

Unrecognized는 UnknownOutcomeCode로 두 경우를 구분하세요. 값이 있으면 서버가 보낸 결과 코드를 이 SDK 버전이 알지 못한다는 뜻이고, 비어 있으면 SDK는 아는 결과지만 레시피에 해당 값이 아직 없다는 뜻입니다. 어느 쪽이든 UnknownOutcomeCode와 RawJson을 기록한 뒤 실패로 처리하고, 값을 추측해 분기하지 마세요.

거절을 기록할 때는 어느 단계에서 멈췄는지 알려 주는 FailedStep을 함께 남기세요. 진단용 값이므로 앱 로직을 이 값으로 분기하지 마세요.

예외

예상할 수 있는 호출 결과는 결과 객체로 반환합니다. 반면 SDK를 초기화하지 않았거나, 필요한 모듈을 등록하지 않았거나, 설정 값이 잘못된 경우처럼 앱 코드를 고쳐야 하는 문제는 예외로 발생합니다. 예외는 실행 중에 분기해 처리할 대상이 아니므로, 발생 조건을 확인해 호출 코드나 설정을 고치세요.

API 예외 발생 조건
HiveCore.Resolve<T>() InvalidOperationException SDK를 초기화하기 전에 호출했습니다.
HiveCore.Resolve<T>() RegistrationNotFoundException 요청한 서비스가 등록되어 있지 않습니다. SDK를 초기화할 때 해당 모듈을 등록하지 않았거나, 지원하지 않는 플랫폼에서 Add-on을 요청한 경우입니다.
CoreConfigBuilder.Build() ArgumentException, ArgumentOutOfRangeException App ID가 비어 있거나, 제한 시간이나 재시도 설정 값이 허용 범위를 벗어났습니다.
요청 객체를 받는 메서드 ArgumentNullException 요청 객체로 null을 전달했습니다.
Add-on 메서드 ArgumentException 상품 ID 목록처럼 값이 있어야 하는 인자를 비워 두고 호출했습니다.

호출 취소는 예외가 아니라 Cancelled Failure로 반환됩니다. SDK 초기화에서 발생하는 예외는 Core 모듈을, 메서드별 발생 조건은 각 메서드 레퍼런스의 '발생 예외' 표를 참조하세요.

저장된 인증 정보 보존

기기에 저장한 액세스 토큰, 리프레시 토큰, 게스트 계정의 guestToken은 사용자가 계정으로 돌아오는 수단입니다. 게스트 계정은 이 값을 잃으면 계정을 되찾을 수 없으므로, 삭제는 되돌릴 수 없는 처리로 다루세요. 기본은 보존이며, 아래 상황별 기준에서 삭제하도록 정한 경우에만 삭제합니다.

인증 정보는 사용자의 명시적 요청이 성공으로 확정되었거나, 특정 인증 정보가 무효라고 서버가 확정한 경우에만 삭제하세요. 확정되지 않은 오류에서 삭제하면 일시적인 장애가 계정 접근 수단의 영구 유실로 이어집니다. 무효 판정은 판정 대상이 된 인증 정보에만 적용됩니다. 예를 들어 리프레시 토큰이 무효라는 판정은 게스트 계정의 guestToken을 지울 근거가 되지 않습니다.

로그아웃

로그아웃 결과에 따라 저장된 인증 정보를 아래와 같이 처리합니다.

  • 성공: 삭제
  • 네트워크·서버 오류: 보존하고 로그아웃을 다시 시도
  • 호출 취소: 보존. 단, 취소했더라도 결과가 성공이면 서버가 이미 로그아웃을 처리한 것이므로 삭제합니다.
  • 기능별 결과나 UnknownOutcome: 보존

로그아웃이 네트워크·서버 오류로 끝나면 서버가 로그아웃을 처리했는지 알 수 없습니다. 이때 인증 정보를 지우면 서버에 남은 세션을 다시 끊을 방법이 없어질 수 있습니다.

계정 삭제

계정 삭제 결과에 따라 저장된 인증 정보를 아래와 같이 처리합니다.

  • 성공: 삭제
  • 기능별 결과나 UnknownOutcome: 보존
  • 네트워크·서버 오류: 보존하고 요청을 다시 시도

토큰 갱신

토큰 자동 갱신이 실패한 원인에 따라 저장된 인증 정보를 아래와 같이 처리합니다. 갱신 실패가 호출 결과로 어떻게 전달되는지는 토큰 자동 갱신 실패를 참조하세요.

  • 서버가 리프레시 토큰을 무효로 판정: 무효가 확정된 토큰을 삭제하고 다시 로그인하는 흐름 제공
  • 판정 없는 실패나 갱신 중단: 보존

보안 저장소

인증 정보를 보관한 보안 저장소의 작업 결과에 따라 저장된 인증 정보를 아래와 같이 처리합니다. 결과별 의미는 ISecureStorage의 결과 처리를 참조하세요.

  • 읽기 실패나 알 수 없는 결과: 보존. 저장소를 비우지 마세요.
  • 접근 거부: 보존. 저장소를 비우지 말고 사용자에게 권한 상태를 안내하세요.
  • 데이터 손상: 저장소를 비우고 다시 로그인하는 흐름 제공

새 인증 정보 저장

새로 받은 인증 정보의 형식을 읽지 못하거나 필수 값이 없으면 기존 인증 정보를 덮어쓰지 말고 보존하세요.

세션 복원

저장한 인증 정보로 세션을 복원할 때는 액세스 토큰을 먼저 검증한 뒤 세션을 등록하세요. 검증 결과의 Player ID가 저장해 둔 값과 다르면 저장한 값을 지우지 말고 다시 로그인하도록 안내하세요. 세션이 끝났다고 OnSessionExpired가 항상 발생하지는 않으므로, 이벤트만으로 판단하지 말고 IsLoggedIn도 함께 확인하세요.