0

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?

Gokul Nath KP
  • 15,485
  • 24
  • 88
  • 126
  • 1
    I was having the similar requirement & had created a wrapper for all API calls. Have a look at this if it helps you: https://stackoverflow.com/a/45457595/1852343 – Sandip Fichadiya Apr 03 '18 at 10:32

2 Answers2

4

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

Raluca Lucaci
  • 2,058
  • 3
  • 20
  • 37
1

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();
Rehan Sarwar
  • 994
  • 8
  • 20