【发布时间】:2017-12-15 08:14:30
【问题描述】:
我有一个ViewPager,并且在同时加载ViewPager 时进行了三个Web 服务调用。
当第一个返回 401 时,调用 Authenticator 并刷新 Authenticator 内的令牌,但剩余的 2 个请求已经使用旧的刷新令牌发送到服务器,并且在拦截器和应用程序中捕获的 498 失败登出。
这不是我所期望的理想行为。我想将第二个和第三个请求保留在队列中,并在刷新令牌时重试排队的请求。
目前,我有一个变量来指示Authenticator 中是否正在进行令牌刷新,在这种情况下,我会取消Interceptor 中的所有后续请求,并且用户必须手动刷新页面,否则我可以注销用户并强制用户登录。
对于上述问题,使用 okhttp 3.x for Android 有什么好的解决方案或架构?
编辑:我想解决的问题是一般性的,我不想对我的电话进行排序。即等待一个调用完成并刷新令牌,然后仅在活动和片段级别发送请求的其余部分。
请求了代码。这是Authenticator的标准代码:
public class CustomAuthenticator implements Authenticator {
@Inject AccountManager accountManager;
@Inject @AccountType String accountType;
@Inject @AuthTokenType String authTokenType;
@Inject
public ApiAuthenticator(@ForApplication Context context) {
}
@Override
public Request authenticate(Route route, Response response) throws IOException {
// Invaidate authToken
String accessToken = accountManager.peekAuthToken(account, authTokenType);
if (accessToken != null) {
accountManager.invalidateAuthToken(accountType, accessToken);
}
try {
// Get new refresh token. This invokes custom AccountAuthenticator which makes a call to get new refresh token.
accessToken = accountManager.blockingGetAuthToken(account, authTokenType, false);
if (accessToken != null) {
Request.Builder requestBuilder = response.request().newBuilder();
// Add headers with new refreshToken
return requestBuilder.build();
} catch (Throwable t) {
Timber.e(t, t.getLocalizedMessage());
}
}
return null;
}
}
类似这样的一些问题: OkHttp and Retrofit, refresh token with concurrent requests
【问题讨论】:
-
请贴一些代码
-
你能发布你的验证码吗?谢谢。还有为什么你用过期的令牌从你的 api 得到 498?
-
@savepopulation 498 表示无效令牌。与第一个请求一起发送的 2 个请求具有旧令牌,请求失败并出现 498 错误代码。
-
那么当您获得刷新的令牌时,是什么阻止您重复第二和第三次请求?
-
@matrix 我必须在拦截器中对失败的请求进行排队,并使用新的刷新令牌重试。首先,我必须有一个事件来通知新的刷新令牌可用,然后我必须重试所有失败的请求。我还没有找到在拦截器中做到这一点的方法。此外,这似乎不是一个好的解决方案,我想知道使用 okhttp 刷新令牌的常见模式是什么
标签: java android http retrofit okhttp