使用拦截器获取refreshtoken后如何调用相同的请求?
Posted
技术标签:
【中文标题】使用拦截器获取refreshtoken后如何调用相同的请求?【英文标题】:How to call the same request after getting refreshtoken using interceptor? 【发布时间】:2020-03-19 10:20:20 【问题描述】:我正在创建使用改造的 android 应用程序。我用spring作为rest api。我已经使用 JWT 进行身份验证。我在这里使用了两个拦截器RequestInterceptor
和ResponseInterceptor
。使用 expire JWT 调用BASE_URL/hello
api 的场景如下
客户端调用 /hello 使用 RequestInterceptor
标头中的过期访问令牌
服务器检查令牌和响应代码为 401/403
客户端检查响应代码并使用 ResponseInterceptor
调用 /refresh,并在 header 中使用 refreshtoken
服务器检查刷新令牌并使用新的访问令牌响应
现在的问题是如何再次调用 /hello。对于每个请求,我都想要这个。我如何预测最后发出的请求。
代码如下:
调用 /hello 的部分代码
btnNext.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
Call<HelloResponse> call= RetrofitFactoryWithJwt.getRetrofitInstance(getApplicationContext()).helloUser();
call.enqueue(new Callback<HelloResponse>()
@Override
public void onResponse(Call<HelloResponse> call, Response<HelloResponse> response)
Log.d(TAG,"after call in enque");
if(response.code()==200)
Log.d(TAG,response.body().getSuccess());
else
Log.d(TAG,"problem in response:"+response.code());
@Override
public void onFailure(Call<HelloResponse> call, Throwable t)
Log.d(TAG,"onfailure"+t.getMessage());
);
Intent intent = new Intent( getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
);
RequestInterceptor.java
public class RequestInterceptor implements Interceptor
Context context;
String TAG="heyrequest";
public RequestInterceptor(Context context)
this.context=context;
@Override
public Response intercept(Chain chain) throws IOException
Request originalRequest = chain.request();
//if url is /refresh add refresh token in header instead of accesstoken
if(originalRequest.url().encodedPath().equalsIgnoreCase("/refresh"))
SharedPreferences preferences = context.getSharedPreferences("tokens", MODE_PRIVATE);
String refreshvalue=preferences.getString("refreshtoken","");
// rewrite the request
Request newRequest=originalRequest.newBuilder()
.addHeader("Authorization","Bearer "+refreshvalue)
.build();
return chain.proceed(newRequest);
//for context we have use requestinterceptor context construction
SharedPreferences preferences = context.getSharedPreferences("tokens", MODE_PRIVATE);
String tokenvalue=preferences.getString("accesstoken","");
// rewrite the request
Request newRequest=originalRequest.newBuilder()
.addHeader("Authorization","Bearer "+tokenvalue)
.build();
return chain.proceed(newRequest);
ResponseInterceptor.java
public class ResponseInterceptor implements Interceptor
Context context;
String TAG="heyresponse";
String accesstoken=null;
Response response=null;
public ResponseInterceptor(Context context)
this.context=context;
@Override
public Response intercept(final Chain chain) throws IOException
final Request request=chain.request();
response = chain.proceed(request);
if(response.code()==401 || response.code()==403)
accesstoken=getNewToken();
return chain.proceed(request);
public String getNewToken()
Call<RefreshResponse> call= RetrofitFactoryWithJwt.getRetrofitInstance(context).refreshToken();
call.enqueue(new Callback<RefreshResponse>()
@Override
public void onResponse(Call<RefreshResponse> call, retrofit2.Response<RefreshResponse> response1)
Log.d(TAG,"in refreshtoken call");
if(response1.code()==200)
accesstoken=response1.body().getAccesstoken();
Log.d(TAG,accesstoken);
SharedPreferences preferences = context.getSharedPreferences("tokens", MODE_PRIVATE);
preferences.edit().putString("accesstoken", accesstoken).apply();
else
Log.d(TAG,"problem in response:"+response1.code());
@Override
public void onFailure(Call<RefreshResponse> call, Throwable t)
Log.d(TAG,"onfailure:"+t.getMessage());
);
return accesstoken;
【问题讨论】:
【参考方案1】:我通过使用验证器处理响应和拦截器在请求中添加标头解决了这个问题
【讨论】:
以上是关于使用拦截器获取refreshtoken后如何调用相同的请求?的主要内容,如果未能解决你的问题,请参考以下文章
Alamofire refreshToken with Retrier:如何获取 refreshToken 请求的状态并重新路由到 LoginView