Retrofit Authenticator 被调用但不工作

问题描述

一开始我很抱歉我的英语不好。 我正在开发一个带有 nodejs 后端的 android 应用程序。JWT 用于授权,因此我将访问令牌发送到服务器以授权我的请求。访问令牌寿命很短,会在 60 秒后过期。为了刷新访问令牌,应用程序必须将刷新令牌发送到服务器。为此,我使用 OkHttp 身份验证器,但身份验证器不起作用。任何机构都可以帮我解决这个问题

服务生成

public class ServiceGenerator {

    private static final OkHttpClient httpClient =
            new OkHttpClient.Builder()
                    .retryOnConnectionFailure(true)
                    .build();

    private static final Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create());

    public static Retrofit retrofit = builder.build();

    public static <S> S createService(Class<S> serviceClass) {
        Retrofit retrofit = builder.client(httpClient).build();
        return retrofit.create(serviceClass);
    }

    public static <S> S createServiceWithAuth(Class<S> serviceClass,String accesstoken,Context context) {
        OkHttpClient newClient = httpClient.newBuilder().addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {

                Request request = chain.request();
                Request.Builder builder = request.newBuilder();

                if(!accesstoken.isEmpty()){
                    builder.addHeader("x-auth-token",accesstoken);
                }
                request = builder.build();
                return chain.proceed((request));
            }
        }).authenticator(CustomAuthenticator.getInstance(accesstoken,context))
                .build();
        Retrofit newRetrofit = retrofit.newBuilder().client(newClient).baseUrl(API_BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
        return newRetrofit.create(serviceClass);
    }

}

自定义身份验证器


public class CustomAuthenticator implements Authenticator {

    private String accesstoken;
    private static CustomAuthenticator INSTANCE;
    Context context;


    private CustomAuthenticator(String accesstoken,Context context){
        this.accesstoken = accesstoken;
        Hawk.init(context).build();
        this.context = context;
    }

    static synchronized CustomAuthenticator getInstance(String accesstoken,Context context){
        if(INSTANCE == null){
            INSTANCE = new CustomAuthenticator(accesstoken,context);
        }
        return INSTANCE;
    }

    @Nullable
    @Override
    public Request authenticate(@Nullable Route route,@NotNull Response response) throws IOException {

        if(responseCount(response) >= 2){
            return null;
        }

        apiclient client = ServiceGenerator.createService(apiclient.class);
        User user = new User();
        user.setRefreshToken(Hawk.get("RefreshToken"));
        Call<User> refreshAccesstokenCall = client.refresh(user);
        retrofit2.Response<User> res = refreshAccesstokenCall.execute();

        if(res.isSuccessful()){
            assert res.body() != null;
            String accesstoken = res.body().getAccesstoken();
            Hawk.put("Accesstoken",accesstoken);

            return response.request().newBuilder().addHeader("x-auth-token",res.body().getAccesstoken()).build();
        }else{
            return null;
        }
    }

    private int responseCount(Response response){
        int result = 1;
        while ((response = response.priorResponse()) != null){
            result++;
        }
        return result;
    }
}

以及将数据 POST 到服务器的方法(在 Fragment 中)

    private void saveExpert() {

        if (!validate()) {
            return;
        }

        progressBar.setVisibility(View.VISIBLE);
        Objects.requireNonNull(getActivity()).getwindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

        String first_and_last_name = firstAndLastName.getText().toString();
        String national_code = nationalCode.getText().toString();
        String phone_number = phoneNumber.getText().toString();
        String home_office_city = homeOfficeCity.getText().toString();
        String _address = address.getText().toString();
        String _field = field.getText().toString();
        String sub_field = subField.getText().toString();
        String _grade = grade.getText().toString();


        apiclient client = ServiceGenerator.createServiceWithAuth(apiclient.class,Hawk.get("Accesstoken"),getContext());
        SetExpert setExpert = new SetExpert(first_and_last_name,national_code,phone_number,home_office_city,_address,_field,sub_field,_grade);
        Call<Expert> expertCall = client.saveExpert(setExpert);
        expertCall.enqueue(new Callback<Expert>() {
            @Override
            public void onResponse(@NotNull Call<Expert> call,@NotNull Response<Expert> response) {
                if (response.isSuccessful()) {
                    Expert expert = response.body();
                    if (expert != null) {
                        Hawk.init(Objects.requireNonNull(getContext())).build();
                        Hawk.put("ExpertNationalCode",expert.getNational_code());
                        progressBar.setVisibility(View.GONE);
                        Objects.requireNonNull(getActivity()).getwindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                        new MaterialDialog.Builder(Objects.requireNonNull(getContext()))
                                .typeface("IRANSansWebMedium.ttf","IRANSansWeb.ttf")
                                .title("پیام سیستم")
                                .content(expert.getFirst_and_last_name() + " عزیز با تشکر از ثبت نام شما. این ثبت نام به منزله تایید نهایی نبوده و پس از بررسی مشخصات و مدارک، با شما تماس گرفته خواهد شد.")
                                .positiveText("تایید.")
                                .canceledOnTouchOutside(false)
                                .onPositive(new MaterialDialog.SingleButtonCallback() {
                                    @Override
                                    public void onClick(@NonNull MaterialDialog dialog,@NonNull DialogAction which) {
                                        dismiss();
                                    }
                                })
                                .show();
                    }
                } else {
                        ApiError apiError = ErrorUtils.parseError(response);
                        progressBar.setVisibility(View.GONE);
                        Objects.requireNonNull(getActivity()).getwindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                        Toast.makeText(getContext(),apiError.getMessage(),Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(@NotNull Call<Expert> call,@NotNull Throwable t) {
                progressBar.setVisibility(View.GONE);
                Objects.requireNonNull(getActivity()).getwindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                Toast.makeText(getContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
            }
        });
    }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)