V1(1.21.1) accessToken 상태에 관련한 문의입니다

image

 KOSession* session = [KOSession sharedSession];

[KOSessionTask accessTokenInfoTaskWithCompletionHandler:^(KOAccessTokenInfo *accessTokenInfo, NSError *error) {
    if (error) {
        RCTLogInfo(@"Error=%@", error);
        reject(getErrorCode(error), error.localizedDescription, error);
    } else {
        resolve(@{@"accessToken": session.token.accessToken,
                 @"refreshToken": session.token.refreshToken});
    }
}];

안녕하세요, 위의 코드에서 사진과 같은 에러가 발생하는데요

accessTokenInfoTaskWithCompletionHandler 가 실행되고 에러가 없다는건
= 토큰 정보를 확인하는데 문제가 없다 = 유효한 토큰이 존재한다? 라는 의미일 텐데
session.token.accessToken 를 확인하면 nil 값이 반환되고 NSDictionary 를 생성하는데서 에러가 발생합니다.

해당 이슈가 프로덕션 환경에서 간헐적으로 발생하는데
타이밍이나 로직상, accessTokenInfoTaskWithCompletionHandler을 정상적으로 요청한 뒤에
session.token.accessToken이 nil 로 반환이 되는 경우가 있을 수 있나요?

ex) completion handler 실행과 api 콜로 인한 accessToken 업데이트가 동시에 비동기로 실행된다 라던지…

몇가지 질문이 있습니다.

  • 사용하시는 ios sdk version 좀 알려주셔요.
  • 혹시 accessTokenInfo를 호출해서 주기적으로 토큰갱신을 하시는건가요?
  • 저 현상이 발생하는 전후 상황에 close() 를 호출하는 곳은 전혀 없을까요?
  • 콜스택을 보고 예상컨데 크래시가 난 getToken()의 실행순서는 명확하게 accessTokenInfo() 컴플리션핸들러까지 호출된뒤에 실행되는 것일까요?

안녕하세요 답변 감사합니다.

  • SDK - v1.21.1 / Client - iOS 13.5.1(iPhone XS Arch:arm64e)
  • 로그인이 된 유저에 한해 앱 최초 실행시마다, 토큰 갱신을 목적으로 accessTokenInfo 호출 하고있습니다.
  • 로그아웃 시점 이외에 별도로 close 를 호출하는 곳은 없습니다.
  • getTokens() 함수 내부에 accessTokeInfoTaskWithCompletionHandler 가 있습니다.

시나리오

  1. [Jul 31, 4:33:06 pm KST] 앱 실행(앱 다운로드 이후 최초 실행)
  2. [Jul 31, 4:33:42 pm KST] 카카오 SDK 로그인 > 카카오 accessToken 을 백엔드에 전송
  3. [Jul 31, 4:33:43 pm KST] 백엔드에서 firebase 인증을 이용해서 카카오 정보로 계정 생성한 뒤, firebase custom token 발급해서 응답
  4. [Jul 31, 4:33:43 pm KST] firebase custom token 수신 > firebase 로그인
  5. [Jul 31, 4:33:45 pm KST] 카카오 SDK accessTokenInfo 호출 > 크래시
  6. [Jul 31, 4:33:49 pm KST] 앱 재실행(두번째 실행)
  7. [Jul 31, 4:33:49 pm KST] firebase 자동 로그인
  8. [Jul 31, 4:33:49 pm KST] 카카오 SDK accessTokenInfo 호출 > 정상 동작

추가로 React Native 로 개발이 되어서, Android 에서도 동일한 로직을 수행하지만 iOS 환경에서만 발생했습니다.
콜스택과 코드 원문 첨부드립니다!

image
image

네. 특별한 문제는 없어보이는데 사용하시는 app id 좀 알수 있을까요?

219327 입니다.

서버응답

일단 해당시간 July 31st 2020, 16:33:45.028 에
서버로그에는 응답도 위와 같이 정상적으로 나간걸로 보이고
크래시가 난 부분은 단순 response 파싱부분이라 sdk 코드에도 문제점은 보이지 않습니다.

사용하시는 프레임웍과 관련된 이슈일 가능성이 커 보입니다.

이질문에 대한 대답을 안드린것같은데
결론부터 말씀드리자면 있을수 있습니다.

accessTokenInfo 호출시 엑세스토큰이 만료되었다면 sdk내부에서 (만료되지 않은 리프레시토큰으로)엑세스토큰갱신을 하게되는데 이때 엑세스토큰 갱신실패가 날경우 기존 토큰이 삭제 될수 있습니다.
그때는 session.token.accessToken이 nil 로 반환됩니다.

타이밍에 의한 부분은 컴플리션 핸들러내에서만 처리하면 문제 없을것으로 보입니다.

1개의 좋아요

네… 로직상 저도 전혀 문제가 없어야 된다고 생각하는데, 문제가 발생하는 유저들이 있어서 난감하네요

프레임 워크에서 발생하는 크래시는 그냥 NSNull 로 처리하면 되는 문제이지만
근본적 원인은 SDK에서 accessTokenInfo API 호출 이후의 completionHandler 에서
accessToken 을 조회했을때 nil 을 반환하는게 원인입니다.


요약하자면,

0. 앱을 최초 설치
1. 카카오 로그인
2. accessTokenInfo 를 호출
3. accessTokenInfo 의 completionHandler 에서 session.token.accessToken 을 호출하면 간헐적으로 nil 이 나온다.
(NSDictionary 를 선언할 때 value 에 [NSNull null] 이 아닌, nil 이 들어가게 되면 크래시가 발생하는데, session.token.accessToken 을 NSDictionary 에 넣는 라인에서 nil 이 들어가 크래시가 발생합니다.)

입니다.


저도 딱히 답이 안보이네요, 토큰 갱신하는게 크게 중요한 기능은 아니라서
혹시나 시간날때 면밀히 살펴봐주시면 감사하겠습니다!

소중한 시간 내주셔서 감사합니다 :slight_smile:


(로그인 직후 API를 호출한 뒤, completionHandler 에서 token 호출시 nil 로 반환되는게
이 글도 관련되어있어 보이는 이슈같네요, accessToken 가져올때 에러나는 이유를 알고 싶습니다)

1개의 좋아요

안녕하세요, 다시 답변을 남겨서 죄송합니다… ㅎㅎ

헤더를 보다가 아래의 정보를 확인했는데요

/*!
 * @property automaticPeriodicRefresh
 * @abstract access token의 자동 주기적 갱신 여부 설정. 해당 값이 YES일 경우 handleDidBecomeActive 및 특정 시간 주기로 필요시 토큰을 자동 갱신함.
 * @discussion 값을 설정하면 현재 토큰 상태에 따라 타이머를 설정하거나 갱신이 필요할 경우 바로 갱신합니다. 이 속성 값은 기기에 저장되지 않고 메모리에서만 유지되므로 AppDelegate의 application:didFinishLaunchingWithOptions: 메소드 내에서 설정하는 것을 권장합니다. iOS 특성상 앱이 백그라운드로 내려가거나 suspend 상태가 되면 갱신이 불가능합니다.
 * @seealso token
 */

혹시 automaticPeriodicRefresh 가 켜져있을때 handleDidBecomeActive 에서 일어나는 자동 갱신 로직으로 인해
아래의 시나리오가 발생 할 가능성이 있을까요?


[KOSession sharedSession].automaticPeriodicRefresh = YES;

  1. 앱 최초 실행 (KOSession 이 닫힌상태)

  2. 로그인 Start

  3. Kakao 앱으로 전환 [applicationDidEnterBackground]

  4. Kakao 로그인 완료 후 앱으로 전환 [applicationDidBecomeActive]

  5. 아래 두개의 로직이 동시에 실행
    5-1 [applicationDidBecomeActive][KOSession handleDidBecomeActive] 토큰 자동 갱신 로직 수행
    (가설: 토큰 자동 갱신과 관련된 로직 실행이 되었으나, 타이밍적인 이슈로 KOSession 닫힌것으로 판단되어 토큰 초기화하는 로직 비동기 실행?)

    5-2. 로그인 정보를 수신한 뒤, 앱에서는 이어서 다음 코드인 accessTokenInfoTaskWithCompletionHandler 호출

  6. 5-2 의 accessTokenInfoTaskWithCompletionHandler 요청은 성공되었으나
    가설: completionHandler 에서 5-1 의 로직이 비동기로 함께 수행되며 타이밍적인 이슈 발생

  7. completionHandler 에서 accessToken 이 nil 로 반환

흠. 주기적 자동갱신은 sdk를 사용하는 모앱의 리소스(타이머)를 사용하고, 유저의 액션과 상관없이 실행될 수 있습니다. 그렇기때문에 언제든 예상하지 못한 문제가 발생할 수 있어 사용을 권장하지 않습니다.
그래서, 곧 정식배포될 sdk v2에서는 삭제된 기능입니다.

게다가 직접 갱신을 accessTokenInfo로 하시는것 같은데 더욱이 주기적갱신을 하실 필요가 없어보입니다.
(자동갱신은 삭제하는것이 좋을거같습니다.)

그리고,
sdk v2가 현재는 beta.7 까지 배포된 상태이며 다음주에 정식배포가 될 예정입니다. sdk v2 많이 이용해주세요.
https://developers.kakao.com/docs/latest/ko/sdk-download/ios

사용자 토큰 주기적 갱신
iOS SDK는 API 호출 시 자동으로 사용자 토큰을 갱신하는 기능이 있습니다. 이 기능을 쓰려면 약간의 설정이 필요합니다. iOS 카카오 SDK에서는 두 가지 설정이 필요합니다.

AppDelegate-didFinishLaunchingWithOptions에서 automaticPeriodicRefresh 옵션을 활성화합니다.

문서에는 API 호출 시 자동으로 갱신하려면 사용해야 한다고 기술되어있는데, 필요 없는건가요?
아무튼, 제거하고 배포한뒤 경과를 살펴보겠습니다.

감사합니다.

필수가 아니라 사용자 선택사항 입니다.
그런데, 갱신목적으로 직접 accessTokenInfo를 호출하고 있으니 자동갱신을 할 필요가 없어보입니다.
자동갱신은 잠재적인 문제점을 가지고 있으니 비추천이란 뜻입니다.
( 그게 원인인지는 확실하지 않습니다.)

image

API 호출 시 자동으로 토큰을 갱신하는 기능이 있고
이 기능을 쓰려면 automaticPeriodicRefresh 활성화 및 didEnterBackground 함수를 추가 해야한다.

= accessTokenInfo 와 같은 API 호출할 때, 토큰 갱신을 시키려면 automaticPeriodicRefresh 를 활성화 시켜라

이 말이 아닌가요…?

아닙니다. 자동갱신은 말그대로 아무것도 하지않고 타이머에 의존해서 갱신하는것을 의미합니다.
(디벨로퍼사이트 개편으로 인한 가이드 오류인것같습니다. 수정조치 하겠습니다. 죄송합니다.)

그리고, 위의 자동갱신과는 별개로 토큰을 사용하는 api 호출시 갱신은
api호출시 토큰만료에러가 떨어지면 원래 api는 pending 상태로 남아있게되고
토큰갱신을 하고 갱신이 성공하게되면 그 후 월래 api 호출을 resume 하는 구조입니다.

1개의 좋아요

넵 별개로 동작하는것이었군요
답변 감사합니다.

1개의 좋아요

로그인 직후, api를 호출하던 코드를 500ms 정도 지연시키니
더이상 해당 에러는 발생하지 않았습니다.

1개의 좋아요