任务
我遇到的情况是,如果刷新令牌请求返回401,我将通过从房间和内存中清除用户来强制注销。我想从Authenticator或Interceptor内部实现此目的,因此我不必检查401作为对每个呼叫的响应。
身份验证器
public Request authenticate(Route route, Response response) throws IOException {
// if (responseCount(response) >= 3) {
// return null;
// }
//
UserCredentials userCredentials = new
UserCredentials().
CreateRefreshTokenRequest("refresh_token",
requestHeaders.getAccessToken().getRefreshToken(),
oAuthClient.getClientId(),
oAuthClient.getClientSecret());
Request.Builder builder = response.request().newBuilder();
if (accountsServicesHolder.getAccountsServices() == null)
return null;
//this HAS TO BE a Synchronous process. The usual RXjava shenanigans can't be applied here.
try {
//Synchronous call to get new token
AccessToken accessToken = accountsServicesHolder.
getAccountsServices().
refreshToken(userCredentials.toMap()).
blockingGet();
//persist the token in the db
//userDao.save()
//persist the token in memory
//send an updated version to the backend
builder.header("Authorization", "Bearer " + accessToken.getAccessToken());
} catch (Exception ex) {
if (ex instanceof HttpException) {
return builder.
url(linksProvider.getProductionUrl().concat(logoutEndpoint)).
build(); //Redirecting this authenticator to a logout ws so that we do not get a 401 . Something goes wrong here
}
}
return builder.build();
}
如您所见,如果我们没有基于刷新令牌的令牌,那么我很狡猾地在构建器中插入一个新URL。这样一来,我就不会出现401冒泡到最初发出呼叫的位置的情况。我不希望用户收到“ 401您尚未授权”消息,而是显示一个吐司说“会话已过期”
请求拦截器
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder builder = original.newBuilder().
header("Authorization", "Bearer " + requestHeaders.getAccessToken().getAccessToken()).
header("Accept-Language", requestHeaders.getLanguage()).
method(original.method(), original.body());
Request newRequest = builder.build();
Response response = chain.proceed(newRequest);
if (response.code() == 200
&& response.request().url().toString().contains("logout")) {
forceUserOut();
}
return response;
}
forceUserOut方法向系统广播已发生注销。 由于我们已经针对401进行了保护,因此不会向用户显示任何错误。
问题
好的,现在我们来解决问题。毕竟我以为我被打扰的地方可能并不那么聪明。身份验证器在调用注销API后再运行一段额外的时间,该时间在应该发生两次的事件之后运行。
据我了解,身份验证器应该刚刚执行了注销服务,然后拦截器应该已经开始执行其工作。
但是,身份验证器执行以下操作
1)尝试获取新的访问令牌
2)失败并调用注销API(调用拦截器并广播注销)
3)失败并调用注销API(调用拦截器并广播注销)
4)结束
我知道我可能会破坏OkHttps身份验证机制中的某些内容,但是我可以使用什么其他方法来实现强制注销,而不必以对所有API进行401检查的方式进行?
对于这个长期的问题深表歉意。