我正在创建使用翻新版的android应用程序。我已经使用spring作为rest api。我已经在JWT中使用了身份验证。我在这里使用了两个拦截器RequestInterceptor和ResponseInterceptor。使用到期JWT调用/ hello的场景如下
1。使用RequestInterceptor在标头中具有已过期的访问令牌的客户端调用/ hello
2。服务器检查令牌和响应,代码为401/403
3.client检查响应代码,并使用ResponseInterceptor调用/ refresh,并在头中带有refreshtoken
4。客户端检查刷新令牌并使用新的访问令牌进行响应
现在的问题是如何再次呼叫/ 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;
}
}
您可以使用一个这样的拦截器
public class AuthorizationInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response mainResponse = chain.proceed(chain.request());
Request mainRequest = chain.request();
// if response code is 401 or 403, 'mainRequest' has encountered authentication error
if (mainResponse.code() == 401 || mainResponse.code() == 403) {
Response generateTokenResponse = createAndExecuteGenerateToken();
if (loginResponse.isSuccessful()) {
try {
//Do what you want with body
String jsonData = loginResponse.body().string();
// create the failed request due to authentication and call it again
Request.Builder builder = mainRequest.newBuilder()
.headers(mainRequest.headers())
.addHeader("Authorization","Bearer "+generateTokenResponse.tokenvalue)
.method(mainRequest.method(), mainRequest.body());
mainResponse = chain.proceed(builder.build());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return mainResponse;
}
private Response createAndExecuteGenerateToken() throws IOException {
OkHttpClient client = new okhttp3.OkHttpClient();
Request request = new Request.Builder()
.url(BASE_URL + GENERATE_TOKEN)
.get()
.build();
return client.newCall(request).execute();
}
}