diff --git a/app/src/main/java/org/sopt/dateroad/data/dataremote/interceptor/AuthInterceptor.kt b/app/src/main/java/org/sopt/dateroad/data/dataremote/interceptor/AuthInterceptor.kt index b0c9db514..ae8a5702a 100644 --- a/app/src/main/java/org/sopt/dateroad/data/dataremote/interceptor/AuthInterceptor.kt +++ b/app/src/main/java/org/sopt/dateroad/data/dataremote/interceptor/AuthInterceptor.kt @@ -3,6 +3,7 @@ package org.sopt.dateroad.data.dataremote.interceptor import android.app.Application import android.content.Intent import java.lang.IllegalStateException +import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -25,53 +26,60 @@ class AuthInterceptor @Inject constructor( private val localStorage: UserInfoLocalDataSource, private val context: Application ) : Interceptor { + private val isRefreshing = AtomicBoolean(false) override fun intercept(chain: Interceptor.Chain): Response { val originalRequest = chain.request() - val authRequest = - if (localStorage.accessToken.isNotBlank()) originalRequest.newAuthBuilder() else originalRequest + val authRequest = if (localStorage.accessToken.isNotBlank()) originalRequest.newAuthBuilder() else originalRequest val response = chain.proceed(authRequest) when (response.code) { CODE_TOKEN_EXPIRE -> { response.close() - val refreshTokenRequest = originalRequest.newBuilder().get() - .url("${BuildConfig.BASE_URL}$API/$VERSION/$USERS/$REISSUE") - .patch("".toRequestBody(null)) - .addHeader(AUTHORIZATION, localStorage.refreshToken) - .build() - val refreshTokenResponse = chain.proceed(refreshTokenRequest) - if (refreshTokenResponse.isSuccessful) { - val responseRefresh = - json.decodeFromString( - refreshTokenResponse.body?.string() - ?: throw IllegalStateException("\"refreshTokenResponse is null $refreshTokenResponse\"") - ) + if (isRefreshing.compareAndSet(false, true)) { + try { + val refreshTokenRequest = originalRequest.newBuilder() + .patch("".toRequestBody(null)) + .url("${BuildConfig.BASE_URL}$API/$VERSION/$USERS/$REISSUE") + .addHeader(AUTHORIZATION, localStorage.refreshToken) + .build() - with(localStorage) { - accessToken = "$BEARER${responseRefresh.accessToken}" - refreshToken = "$BEARER${responseRefresh.refreshToken}" - } - - refreshTokenResponse.close() + val refreshTokenResponse = chain.proceed(refreshTokenRequest) - val newRequest = originalRequest.newAuthBuilder() - return chain.proceed(newRequest) - } else { - with(context) { - CoroutineScope(Dispatchers.Main).launch { - startActivity( - Intent.makeRestartActivityTask( - packageManager.getLaunchIntentForPackage(packageName)?.component - ) + if (refreshTokenResponse.isSuccessful) { + val responseRefresh = json.decodeFromString( + refreshTokenResponse.body?.string() + ?: throw IllegalStateException("\"refreshTokenResponse is null $refreshTokenResponse\"") ) - localStorage.clear() + + with(localStorage) { + accessToken = BEARER + responseRefresh.accessToken + refreshToken = responseRefresh.refreshToken + } + refreshTokenResponse.close() + + val newRequest = originalRequest.newAuthBuilder() + return chain.proceed(newRequest) + } else { + with(context) { + CoroutineScope(Dispatchers.Main).launch { + startActivity( + Intent.makeRestartActivityTask( + packageManager.getLaunchIntentForPackage(packageName)?.component + ) + ) + localStorage.clear() + } + } } + } finally { + isRefreshing.set(false) } } } } + return response } @@ -80,8 +88,6 @@ class AuthInterceptor @Inject constructor( companion object { const val CODE_TOKEN_EXPIRE = 401 - const val CONTENT_TYPE = "Content-Type" - const val APPLICATION_JSON = "application/json" const val AUTHORIZATION = "Authorization" const val BEARER = "Bearer " }