【发布时间】:2017-11-07 06:38:10
【问题描述】:
在我的应用程序中,我实现了 Retrofit 来调用 WebServices,并且我使用 OkHttp 来使用拦截器和身份验证器。有些请求需要token,我已经实现了Authenticator接口来处理刷新(遵循官方documentation)。但我有以下问题:有时在我的应用程序中,我必须一次调用多个请求。因此,对于其中一个,我将遇到 401 错误。
这是我的请求调用代码:
public static <S> S createServiceAuthentication(Class<S> serviceClass, boolean hasPagination) {
final String jwt = JWT.getJWTValue(); //Get jwt value from Realm
if (hasPagination) {
Gson gson = new GsonBuilder().
registerTypeAdapter(Pagination.class, new PaginationTypeAdapter()).create();
builder =
new Retrofit.Builder()
.baseUrl(APIConstant.API_URL)
.addConverterFactory(GsonConverterFactory.create(gson));
}
OkHttpClient.Builder httpClient =
new OkHttpClient.Builder();
httpClient.addInterceptor(new AuthenticationInterceptor(jwt));
httpClient.authenticator(new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
if (responseCount(response) >= 2) {
// If both the original call and the call with refreshed token failed,
// it will probably keep failing, so don't try again.
return null;
}
if (jwt.equals(response.request().header("Authorization"))) {
return null; // If we already failed with these credentials, don't retry.
}
APIRest apiRest = createService(APIRest.class, false);
Call<JWTResponse> call = apiRest.refreshToken(new JWTBody(jwt));
try {
retrofit2.Response<JWTResponse> refreshTokenResponse = call.execute();
if (refreshTokenResponse.isSuccessful()) {
JWT.storeJwt(refreshTokenResponse.body().getJwt());
return response.request().newBuilder()
.header(CONTENT_TYPE, APPLICATION_JSON)
.header(ACCEPT, APPLICATION)
.header(AUTHORIZATION, "Bearer " + refreshTokenResponse.body().getJwt())
.build();
} else {
return null;
}
} catch (IOException e) {
return null;
}
}
});
builder.client(httpClient.build());
retrofit = builder.build();
return retrofit.create(serviceClass);
}
private static int responseCount(Response response) {
int result = 1;
while ((response = response.priorResponse()) != null) {
result++;
}
return result;
}
问题很简单,第一个请求会成功刷新令牌,但其他请求会失败,因为他们会尝试刷新已刷新的令牌。 WebService 返回错误 500。有什么优雅的解决方案可以避免这种情况吗?
谢谢!
【问题讨论】:
-
这可能对你有帮助,希望还为时不晚stackoverflow.com/a/48518733/8187386