OkHttp认证器
OkHttp authenticator
我正在使用 OkHttp3
和 Retrofit2
。
需要为所有请求替换令牌。
我写了一个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
.
我正在使用 OkHttp3
和 Retrofit2
。
需要为所有请求替换令牌。
我写了一个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);
}
}
对我有用
Authenticator
,否则使用 Interceptor
以更新您的请求(听众,添加令牌)。
不要使用Interceptor
更新您的令牌。
所以你的 TokenAuthenticator
必须实现 Interceptor
.