-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Authenticator Retry 로직 수정 및 토큰 관리, 에러 처리 보완 (#189)
* Authenticator 함수 내부 구현 변경 401 로 떨어질 경우 refresh 토큰을 헤더에 담아 호출하는 가장 간단한 형태로 변경 * RefreshTokenExpiredException 추가 * Refresh 토큰도 만료될 경우, 로그인 토큰을 제거하고, 로그인 화면으로 돌아가는 로직 구현 내 정보 화면만 해당, 다른 화면도 동일 로직을 적용 시켜야 함 * 회원 가입 API @get -> @post 로 수정, 로그인 뷰모델 에러 핸들링 로직 변경 * 회원 탈퇴할 경우 로그인 토큰을 제거하는 로직 추가 * chore: 필요하지 않은 코드 제거 및 suppress 구문 제거 * chore: @Suppress annotation 원복 및 주석 처리된 코드 제거
- Loading branch information
Showing
10 changed files
with
59 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 22 additions & 25 deletions
47
data/src/main/kotlin/us/wedemy/eggeum/android/data/service/TokenAuthenticator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,44 @@ | ||
package us.wedemy.eggeum.android.data.service | ||
|
||
import javax.inject.Inject | ||
import kotlinx.coroutines.runBlocking | ||
import okhttp3.Authenticator | ||
import okhttp3.Request | ||
import okhttp3.Response | ||
import okhttp3.Route | ||
import javax.inject.Inject | ||
import timber.log.Timber | ||
import us.wedemy.eggeum.android.data.datastore.TokenDataStoreProvider | ||
import us.wedemy.eggeum.android.domain.util.RefreshTokenExpiredException | ||
|
||
@Suppress("TooGenericExceptionCaught") | ||
public class TokenAuthenticator @Inject constructor( | ||
private val dataStoreProvider: TokenDataStoreProvider, | ||
) : Authenticator { | ||
|
||
override fun authenticate(route: Route?, response: Response): Request? { | ||
val accessToken = runBlocking { | ||
dataStoreProvider.getAccessToken() | ||
} | ||
|
||
if (hasNotAccessTokenOnResponse(response)) { | ||
synchronized(this) { | ||
val newAccessToken = runBlocking { | ||
dataStoreProvider.getAccessToken() | ||
} | ||
if (accessToken != newAccessToken) { | ||
return newRequestWithAccessToken(response.request, newAccessToken) | ||
} | ||
Timber.d("authenticate 호출") | ||
return runBlocking { | ||
val currentAccessToken = dataStoreProvider.getAccessToken() | ||
|
||
// 현재 액세스 토큰이 요청 헤더의 토큰과 다르면 이미 갱신된 것으로 간주 | ||
if (response.request.header("Authorization") != "Bearer $currentAccessToken") { | ||
Timber.d("RefreshToken is Expired") | ||
// 로그인 토큰 제거(로그아웃) | ||
dataStoreProvider.clear() | ||
throw RefreshTokenExpiredException | ||
} | ||
|
||
val refreshToken = runBlocking { | ||
dataStoreProvider.getRefreshToken() | ||
} | ||
return newRequestWithAccessToken(response.request, refreshToken) | ||
try { | ||
val newAccessToken = runBlocking { dataStoreProvider.getRefreshToken() } | ||
newRequestWithAccessToken(response.request, newAccessToken) | ||
} catch (e: Exception) { | ||
Timber.e("TokenAuthenticator Error :: ${e.message}") | ||
null | ||
} | ||
} | ||
|
||
return null | ||
} | ||
|
||
private fun hasNotAccessTokenOnResponse(response: Response): Boolean = | ||
response.header("Authorization") == null | ||
|
||
private fun newRequestWithAccessToken(request: Request, accessToken: String): Request = | ||
request.newBuilder() | ||
.addHeader("Content-Type", "application/json") | ||
.addHeader("Authorization", "Bearer $accessToken") | ||
.header("Authorization", "Bearer $accessToken") | ||
.build() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters