Issue
I want to change response from server to 423 -> 401, and then call refreshToken by using Authenticator.
The method is called if response code is 401
But why the method Authenticator.authenticate(Route route, Response response)
is not called in my case?
OkHttpClient
OkHttpClient httpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
//Adding token to request
Request request = chain.request();
Request.Builder builder = request.newBuilder();
builder.header("Authorization", "access_token");
return chain.proceed(builder.build());
}
})
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
//changing response code from server 423 -> 401
Request request = chain.request();
Response response = chain.proceed(request);
if (response.code() == 423)
return response.newBuilder().code(401).build();
return response;
}
})
.authenticator(new Authenticator() {
//THE METHOD IS NOT CALLED, WHY?
@Override
public Request authenticate(Route route, Response response) throws IOException {
// Refresh access_token using a synchronous api request
String newAccessToken = refreshToken();
saveNewToken(newAccessToken)
// Add new header to rejected request and retry it
return response.request().newBuilder()
.header("Authorization", newAccessToken)
.build();
}
})
.build();
Retrofit interface:
ApiService mApiService = new Retrofit.Builder()
.baseUrl(serverHostUrl)
.client(httpClient)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
.create(ApiService.class);
Solution
I think the problem here is the difference between application interceptors
and network interceptors
. You can read all about it here and should do since there are quite some differences.
In your case and in short I think you're changing the response code after OkHttp
has checked the status code and tried to run the authenticator. So the solution would be to change the status code using a network interceptor and not an application interceptor like you have it now.
If you look at method getResponseWithInterceptorChain from RealCall.java
you'll see that the stack of interceptors is built by first adding all the application interceptors and then some internal interceptors and then finally network interceptors. You'll see that one of the internal interceptors is a RetryAndFollowUpInterceptor which seems to deal with the authenticator code here.
So what seems to be happening is that you make your request. The interceptor to change the code runs and calls proceed on the chain. The request goes through all the remaining interceptors, but let's focus on the RetryAndFollowUpInterceptor
. This one will run after yours and proceed in the chain. It gets the response and has a response with code 423
and won't do anything to re-authenticate. It will then return and now it's your interceptor running. It sees a response code 423
and changes it, but this won't run the RetryAndFollowUpInterceptor
again.
As you see, it seems you're changing the code too late or too high up in the application. You'd have to make sure you do that before the RetryAndFollowUpInterceptor
has a chance to look at the response's code and this is easier done with a network interceptor. You'll have to deal with a couple of more things than simply the status code, but it will be possible.
Hope this helps
Answered By - Fred Answer Checked By - Willingham (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.