Search code examples
javaandroidokhttpinterceptorrefresh-token

HttpservletRequest not taking newer refreshtoken at backend side in only refreshtoken api call


I'm using authenticate method of Authenticator(okhttp3) class for to give refreshtoken of apis.
In that method I've calling refreshtoken api using httpClient.addInterceptor for giving new token

but issue create with authorization token

It's giving newer authorization token to other api but in only refreshtoken apicall it's getting their previous authorization token at backend side although at android side giving newer refreshtoken as header

Example:

When run app that time token is "ABC" after it's expired ,new refresh token is "xyw" after "xyw" expired - then it's take "xyw" as oldAccessToken - and newer refreshtoken is "pqr"

now when "pqr" expired then it's take "xyw" instead of "pqr"

it create this problem in only refreshtoken apicall. I can't able to find the main cause of this issue
Can anyone please suggest me why this issue raised ?

Code:

Main api call using post method :

  public static void post(String url, String json, Context context, Callback callback) {
        okHttpClient = new OkHttpClient().newBuilder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .callTimeout(60,TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .authenticator(new TokenAuthenticator(context))
                .addInterceptor(new AccessTokenInterceptor(context)).build();

        RequestBody body = RequestBody.create(json,mediaType);
        System.out.println("J:> 1 main Token ::"+getToken(context));
        Request request = new Request.Builder()
                .url(url)
                .header(AUTHORIZATION,getToken(context))
                .post(body)
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(callback);
    }

AccessTokenInterceptor :

public class AccessTokenInterceptor  implements Interceptor {

    private Context mContext;
    public AccessTokenInterceptor(Context mContext) {
        this.mContext = mContext;
    }

    @NonNull
    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        System.out.println("J:> AUTH intercept inside...");
        Request request = chain.request()
                .newBuilder()
                .addHeader(AUTHORIZATION, APIServices.getToken(mContext))
                .build();


        return chain.proceed(request);

   }
}

TokenAuthenticator:

 public Request authenticate(@Nullable Route route, @NonNull Response response) throws IOException {
     
        if (!response.request().header(AUTHORIZATION).equals(APIServices.getToken(mContext)))
            return null;
        String accessToken = null;

        ApiInterface apiService = getAdapterRefresh(response.request().header(AUTHORIZATION)).create(ApiInterface.class);
        Call<JwtRefreshTokenResponseModel> call = apiService.requestAccessToken();
        try {
            retrofit2.Response responseCall = call.execute();
            JwtRefreshTokenResponseModel responseRequest = (JwtRefreshTokenResponseModel) responseCall.body();
            if (responseRequest != null) {
                String data = responseRequest.getToken();
                accessToken = data;
                //store token in session
            }
    }catch (Exception ex){
        Log.d("ERROR", "onResponse: "+ ex.toString());
        ex.printStackTrace();
    }

        if (accessToken != null) {
            // retry the failed 401 request with new access token
                     return response.request().newBuilder()
                    .header("Authorization", accessToken) // use the new access token
                    .build();
        }else{
            return null;
        }

    }

getAdapterRefresh:

public Retrofit getAdapterRefresh(String token) {
   if (retrofitRefresh==null) { 

      final OkHttpClient.Builder httpClient = new OkHttpClient.Builder().
              connectTimeout(10, TimeUnit.SECONDS)
              .callTimeout(60,TimeUnit.SECONDS)
              .writeTimeout(60, TimeUnit.SECONDS)
              .readTimeout(60, TimeUnit.SECONDS);
            httpClient.addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request()
                            .newBuilder()
                            // add Authorization key on request header
                            // key will be using refresh token
                            .addHeader(AUTHORIZATION,token)
                            .build();
                   return chain.proceed(request);
                }
            });

            Gson gson = new GsonBuilder()
                    .setLenient()
                    .create();
            retrofitRefresh= new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .client(httpClient.build())
                    .build();
        }
        return retrofitRefresh;
    }

Thanks in advance


Solution

  • The main cause was if (retrofitRefresh==null) condition in getAdapterRefresh method.

    I removed this from method , it's working as expected

    Make it like below:

    public Retrofit getAdapterRefresh(String token) {
       final OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
       httpClient.addInterceptor(new Interceptor() {
           @Override
               public Response intercept(Chain chain) throws IOException {
                  Request request = chain.request()
                         .newBuilder()
                         // add Authorization key on request header
                         // key will be using refresh token
                         .addHeader(AUTHORIZATION,token)
                         .build();
                    return chain.proceed(request);
                 }
        });
    
         Gson gson = new GsonBuilder().setLenient().create();
             
         return new Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create(gson))
                        .client(httpClient.build())
                        .build();
        }