Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
432 views
in Technique[技术] by (71.8m points)

refresh token - Retrofit Authenticator called but not work

at the first I am sorry for my poor english. I am developing an android app with nodejs backend.JWT is used for authorization, so I send access token to the server to authorize my request. access token life is short and expire in 60s. for refreshing the access token the app must to send refresh token to server. for this purpose I am using OkHttp authenticator but authenticator is not work. can any body help me to solve this problem

ServiceGenerator

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

}

CustomAuthenticator


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

and method that POST data to server (in 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();
            }
        });
    }
question from:https://stackoverflow.com/questions/65857818/retrofit-authenticator-called-but-not-work

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...