Reputation: 15574
Problem Statement:
I'm using Retrofit in my application for API calls. Currently I've 20+ Retrofit Interfaces, with different Callbacks
. Currently when app receives INVALID_SESSION_ID
in anyone of these Interfaces (say UpdateUserAPI
), I've to get new ACCESS_TOKEN
, by invoking AccessTokenAPI
.
Approach Suggested:
When app receives INVALID_SESSION_ID
in Callback
in UpdateUserAPI
, invoke AccessTokenAPI
to get new ACCESS_TOKEN
. Upon receiving new ACCESS_TOKEN
, post the actual call (with initial parameters in UpdateUserAPI
) with new ACCESS_TOKEN
. But this requires to save parameters in the class which implements UpdateUserAPI
. Also I need to retry getting ACCESS_TOKEN
only once, which should be handled.
What is the best approach to implement above requirement?
Upvotes: 0
Views: 5385
Reputation: 1014
Create your own custom interceptor and check your token/session_id is valid or not. If your session_id is expired and then hit your updateUserAPI to get new id and set this id in header or where you want. Here is some code samples.
RefreshTokenInterceptor
public static class RInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
try {
if (response.code() == 410) {
Response r = null;
try {
r = makeTokenRefreshCall(request, chain);
} catch (JSONException e) {
e.printStackTrace();
}
return r;
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
}
private static Response makeTokenRefreshCall(Request req, Interceptor.Chain chain) throws JSONException, IOException {
/* fetch refreshed token, some synchronous API call, whatever Because we are responsible to return new response */
refreshTokenSync();
Request newRequest;
newRequest = req.newBuilder().header("authorization", NEW_TOKEN)/*.post(req.body())*/.build();
return chain.proceed(newRequest);
}
RESTClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(50, TimeUnit.SECONDS)
.writeTimeout(55, TimeUnit.SECONDS)
.connectTimeout(50, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addInterceptor(new NetworkInterceptor())
.build();
Upvotes: 1
Reputation: 2153
Create your own TokenInterceptor
public class TokenInterceptor implements Interceptor
Then set it to your okktpclient
Interceptor tokenInterceptor = new TokenInterceptor(provideUserLoginDao(appDatabase));
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(tokenInterceptor)
.writeTimeout(50, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build();
Useful information in this post also : Refreshing OAuth token using Retrofit without modifying all calls
Upvotes: 5