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
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();
}