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()
Interceptors, according to the documentation, are a powerful mechanism that can monitor, rewrite, and retry the API call. So, when we make an API call, we can either monitor it or perform some tasks.
Retrofit is used to perform the following tasks: It manages the process of receiving, sending, and creating HTTP requests and responses. It alternates IP addresses if there is a connection to a web service failure. It caches responses to avoid sending duplicate requests.
Retrofit is a type-safe REST client for Android, Java and Kotlin developed by Square. The library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp.
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) {
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With