如何在android中使用拦截器获取更新令牌后如何调用相同的请求

问题描述 投票:-1回答:1

我正在创建使用翻新版的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;
    }

}

java android jwt retrofit2 okhttp
1个回答
0
投票

您可以使用一个这样的拦截器

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

}

© www.soinside.com 2019 - 2024. All rights reserved.