
LoveMarker 프로젝트를 개발하며 발생했던 이슈들을 기록합니다!
액세스 토큰 재발급 API를 호출했는데, 21번이나 중복으로 요청되는 리다이렉션 문제가 발생했다.
HTTP FAILED: java.net.ProtocolException: Too many follow-up requests: 21
https://stackoverflow.com/questions/35132330/retrofit-too-many-follow-up-requests-21

위의 스택오버플로우 글을 통해 원인을 찾을 수 있었다.
요청 헤더에 토큰을 추가할 때, header가 아니라 addHeader 메서드를 사용해서 발생한 문제였다.
addHeader, header 메서드의 차이점은 다음과 같다.
return response.request.newBuilder()
.addHeader("accessToken", newAccessToken)
.build()
Authorization과 같은 헤더는 하나의 값만 가져야 하므로 header를 사용하는 것이 적합하다. return response.request.newBuilder()
.header("accessToken", newAccessToken)
.build()
따라서, addHeader 메서드로 인해 헤더의 값이 중복되면, 서버가 이를 잘못 해석하여 유효하지 않은 요청으로 간주하거나, 반복적인 리다이렉션을 유발할 수 있다.
package com.capstone.lovemarker.core.network.authenticator
class LoveMarkerAuthenticator @Inject constructor(
private val userPreferencesDataSource: UserPreferencesDataSource,
private val reissueTokenService: ReissueTokenService,
@ApplicationContext private val context: Context,
) : Authenticator {
override fun authenticate(route: Route?, response: Response): Request? {
if (response.code == CODE_TOKEN_EXPIRED) {
val newAccessToken = runCatching {
runBlocking {
reissueTokenService.getNewAccessToken(
refreshToken = userPreferencesDataSource.userData.first().refreshToken
)
}.data.accessToken
}.onSuccess { token ->
runBlocking {
userPreferencesDataSource.updateAccessToken(token)
}
}.onFailure { throwable ->
Timber.e("FAIL REISSUE TOKEN: ${throwable.message}")
runBlocking {
userPreferencesDataSource.clear()
}
ProcessPhoenix.triggerRebirth(context)
}.getOrThrow()
// addHeader 대신에 header 사용
return response.request.newBuilder()
.header("accessToken", newAccessToken)
.build()
}
return null
}
companion object {
const val CODE_TOKEN_EXPIRED = 401
}
}