마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

레트로핏 인터셉터 토큰 재호출?

0 추천
토큰 재발급 api를 호출하려는데 어떻게 해야되나요..?

인터셉터에서

val requestBuilder = chain.request.newBuilder()
val request = requestBuilder.build()
val response = chain.proceed(request)

if(response.code == 401) {
 // 여기서 어떻게..?
}

저 주석부분을 어떻게 해야될지모르겠습니다

 

api 호출을 하는 메소드는 끌어와지는데 저기서

저렇게 빌더를 생성해줘야되는데 생성이 안되네요 어떻게 만드는건가요..?
수원통학러 (3,570 포인트) 님이 2022년 3월 31일 질문

1개의 답변

0 추천

Retrofit에 Authenticator라는 녀석이 access token을 갱신할 수 있도록 지원하는데, 님의 use case에 맞는지 모르겠네요.

아래 블로그를 참조해 보세요. 저는 참고로 써보지는 않았습니다.

https://www.simplifiedcoding.net/retrofit-authenticator-refresh-token/

참고로, 인터셉터에서 access token 갱신하려면 여러가지 어려움이 있습니다. 상황에 따라서는 현재 사용자의 로그인상태를 알아야 할 수도 있고, refresh token이 존재해야 보안상 안전합니다. 그리고 interceptor자체가 async가 아니기 때문에 access token 을 비동기로 가져온 다음, 어떻게 interceptor 안에서 리턴할 수 있을지... 잘 안떠오르네요. 401 에러가 올 때 외부로 에러를 던져서 캡쳐하는 쪽에서 access token 갱신을 요청할 수는 있겠지만요. 

저같으면 그냥 API 클래스 핸들링하는 클래스를 하나 만들어서 응답을 체크해서 401이면 access token을 가져오는 클래스를 이용해 access token을 갱신하게 한 다음, 성공하면 요청을 계속할 수 있도록 할 것 같습니다만. RxJava나 Coroutine의 경우는 이 부분이 좀 더 수월해 보입니다만...
제 아이디어는 이렇습니다. Interceptor에서 401일 때 TokenExpiredException(사용자 정의 Exception)을 던집니다. 이렇게 하면 ApiService에서  apiCall 을 할 때 401일 경우 TokenExpiredException를 캡쳐할 수 있을 겁니다. 아래와 코드의 흐름처럼 (머릿속으로만 생각해본 코드임) TokenExpiredException이 리턴된 경우는 access token을 먼저 갱신해서  토큰을 singleton 오브젝트(tokenStore)를 이용해 저장한 다음 apiCall을 합니다.

Tokenstore에서 access token읽어와 Http에 헤더에 설정해주는Retrofit 인터셉터도 필요하겠죠.

class ApiService(
    private val tokenApi: TokenApi,
    private val tokenStore: TokenStore
) {
       suspend fun <T> sendRequest(apiCall: suspend () -> T): T {
           return try {
                 apiCall()
           } catch (e: TokenExpiredException) {
                renewAccessToken()
                apiCall()
           }
       }

      private suspend fun renewAccessToken() {
             val accessToken = tokenApi.renewAccessToken(tokenStore.refreshToken)
             tokenStore.accessToken = accessToken
      }
}

 

spark (227,530 포인트) 님이 2022년 3월 31일 답변
...