【问题标题】:HttpservletRequest not taking newer refreshtoken at backend side in only refreshtoken api callHttpservletRequest 仅在 refreshtoken api 调用中未在后端采用更新的 refreshtoken
【发布时间】:2022-01-22 15:50:29
【问题描述】:

我正在使用Authenticator(okhttp3) 类的authenticate 方法来提供api 的refreshtoken。
在该方法中,我使用 httpClient.addInterceptor 调用 refreshtoken api 来提供新令牌

但使用授权令牌发出 create

它向其他 api 提供更新的授权令牌,但仅在 refreshtoken apicall 中,它在后端获取他们以前的授权令牌,尽管在 android 端提供更新的 refreshtoken 作为标头

示例:

当运行应用程序时,时间标记是“ABC” 过期后,新的刷新令牌是“xyw” 在 "xyw" 过期后 - 然后将 "xyw" 作为 oldAccessToken - 更新的 refreshtoken 是 "pqr"

现在当“pqr”过期时,它会使用“xyw”而不是“pqr”

它仅在 refreshtoken apicall 中产生此问题。 我无法找到此问题的主要原因
谁能告诉我为什么会提出这个问题?

代码:

使用 post 方法调用主 api :

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

   }
}

令牌验证器:

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

提前致谢

【问题讨论】:

  • 我不会在令牌刷新时重建 Retrofit 或 OkHttpClient 实例。您已经有一个拦截器,您只能使用 AccessTokenInterceptor,并检查响应、请求新令牌并更新自身和保存的令牌。然后它都在一个地方,而不是在 Authenticator + Interceptor + DI 之间分开。
  • @YuriSchimke 你能举例说明你在说什么吗?
  • stackoverflow上有很多类似的问题,比如stackoverflow.com/questions/31021725/…stackoverflow.com/questions/55688352/…
  • @YuriSchimke 好的...感谢您的帮助。我会试试的

标签: java android okhttp interceptor refresh-token


【解决方案1】:

主要原因是getAdapterRefresh方法中的if (retrofitRefresh==null)条件。

我从方法中删除了它,它按预期工作

如下所示:

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

【讨论】:

    猜你喜欢
    • 2019-09-01
    • 2022-11-28
    • 2017-05-01
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 2017-10-21
    • 2021-09-29
    • 2016-11-09
    相关资源
    最近更新 更多