使用拦截器获取refreshtoken后如何调用相同的请求?
How to call the same request after getting refreshtoken using interceptor?
我正在创建 android 使用改造的应用程序。我使用 spring 作为休息 api。我已经使用 JWT 进行身份验证。我在这里使用了两个拦截器 RequestInterceptor
和 ResponseInterceptor
。使用expire JWT调用BASE_URL/hello
api的场景如下
客户端使用 RequestInterceptor
在 header 中使用过期的访问令牌调用 /hello
服务器检查令牌和代码为 401/403 的响应
客户端检查响应代码并使用 ResponseInterceptor
和 header
中的 refreshtoken 调用 /refresh
服务器检查刷新令牌并使用新的访问令牌进行响应
现在的问题是如何再次调用/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;
}
}
我通过使用 authenticator 处理响应和拦截器在 request
中添加 header 解决了这个问题
我正在创建 android 使用改造的应用程序。我使用 spring 作为休息 api。我已经使用 JWT 进行身份验证。我在这里使用了两个拦截器 RequestInterceptor
和 ResponseInterceptor
。使用expire JWT调用BASE_URL/hello
api的场景如下
客户端使用
RequestInterceptor
在 header 中使用过期的访问令牌调用 /hello
服务器检查令牌和代码为 401/403 的响应
客户端检查响应代码并使用
ResponseInterceptor
和 header 中的 refreshtoken 调用 /refresh
服务器检查刷新令牌并使用新的访问令牌进行响应
现在的问题是如何再次调用/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;
}
}
我通过使用 authenticator 处理响应和拦截器在 request
中添加 header 解决了这个问题