OkHttp认证器

OkHttp authenticator

我正在使用 OkHttp3Retrofit2。 需要为所有请求替换令牌。 我写了一个TokenAuthentificator class:

   public class TokenAuthenticator implements Authenticator {

        @Override
        public Request authenticate(Route route, okhttp3.Response response) throws IOException {
            return response.request().newBuilder()
                    .header(Const.Url.COOKIE, preferenceHelper.getToken())
                    .build();
        }
    }

并用 Retrofit 初始化它:

@Inject
public RestApi(PreferenceHelper preferenceHelper) {
    TokenAuthenticator authenticator = new TokenAuthenticator();

    this.preferenceHelper = preferenceHelper;
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(interceptor)
            .authenticator(authenticator)
            .connectTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();


    Retrofit retrofit = new Retrofit.Builder().baseUrl(Const.Url.API)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();
    user = retrofit.create(User.class);
}

但是,请求中的header仍然没有被替换。 可能是什么问题?

请求示例:

 @Multipart
    @POST("user_set_photo")
    Observable<Response<TechmasResponse>> setPhoto(@Part("PERSONAL_PHOTO\"; filename=\"image.png\" ") RequestBody file);

在 activity/fragments 中,看起来像这样:

Subscription request = restApi.user.setPhoto(body)
                .compose(RxUtils.applySchedulers())
                .subscribe(this::successAddPhoto, this::handleError);
        unSubscribeOnDestroy(request);

在 SharedPreerences 中存储令牌并从拦截器加载它:

public class TokenAppendingHeaderInterceptor implements Interceptor {

    private TokenStorage tokenStorage;

    public TokenAppendingHeaderInterceptor(TokenStorage tokenStorage){
        this.tokenStorage = tokenStorage;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        String token = tokenStorage.getToken();
        Request newRequest = request.newBuilder()
                .addHeader("Accept", "application/json")
                .addHeader("sessionId", token)
                .addHeader("application-type", "REST")
                .build();
        return chain.proceed(newRequest);
    }
}

对我有用

当您请求 returns 401 并且您需要更新您的令牌时使用

Authenticator,否则使用 Interceptor 以更新您的请求(听众,添加令牌)。

不要使用Interceptor更新您的令牌

所以你的 TokenAuthenticator 必须实现 Interceptor.