I have an issue where I am trying to refresh an access token inside my interceptor. I have read it is better to use an Authenticator for this issue, but the way my API works is that I get a 403 error for an unauthorized access token (not my design but gotta work with it).
So I am trying to call the API endpoint to get a new access token inside my interceptor but it seems like the second API call creates an OKHTTP Response without closing it.
override fun intercept(chain: Interceptor.Chain?): Response {
var currentRequest = chain!!.request()
val currentRequestResponse = chain.proceed( currentRequest )
if ( currentRequestResponse.code() >= HTTP_ERROR_CODE && isNotLoginRequest( chain ) ) {
try {
// we check the response code, if there is 403 code we need to relog the user
// before executing the request
// try to reconnect the user with synchronous request
val userManager = UserManager.getInstance()
val clientId = getQueryParameter(UserService.CLIENT_ID_QUERY_KEY, currentRequest)
val redirectUri = getQueryParameter(UserService.REDIRECT_URI_QUERY_KEY, currentRequest)
val clientSecret = getQueryParameter(UserService.CLIENT_SECRET_QUERY_KEY, currentRequest)
// we get a new access token with a synchronous request
val accessToken = userManager.refreshToken(clientId, clientSecret, redirectUri)
currentRequest = rebuildRequestWithNewToken( accessToken, currentRequest )
return chain.proceed( currentRequest )
} catch (e: Throwable) {
e.printStackTrace()
}
}
return currentRequestResponse
}
I believe the problem comes from the userManager.refreshToken which is the API call to get the new access token.
Here is the error I receive:
java.lang.IllegalStateException: cannot make a new request because the previous response is still open: please call response.close()
You can make the refresh token call inside the network interceptor like this
if (response.code() == 403) {
try {
val body = RequestBody.create(contentType, "")
val authRequest = request.newBuilder()
.setDefaultHeaders()
.addHeader("Authorization", "Your token")
.url(refreshtokenurl)
.post(body)
.build()
val tokenRefreshResponse = chain.proceed(authRequest)
if (tokenRefreshResponse.code() == 401 || tokenRefreshResponse.code() == 403) {
//error in refreshing token
} else if (tokenRefreshResponse.code() == 200) {
//save the new token and refresh token in preference and continue with the earlier request
currentRequestResponse = chain.proceed(currentRequest.newBuilder()
.setDefaultHeaders()
.addHeader(your header)
.build())
}
} catch (e: Exception) {
}
}