问题描述
一开始我很抱歉我的英语不好。 我正在开发一个带有 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 (将#修改为@)