网上搜了一大圈token刷新机制的处理,发现都不是特别完善。产生的问题如下:
- 没关注到并发的问题
- 关注了并发,却把所有请求都做成了串行
于是基于自己的理解以及stackoverflow查到的一些线索,重新实现了一套,希望抛砖引玉,有经验的同学可以一起讨论,不吝赐教。
基本原理
利用okhttp的Authenticator
public class MyAuthenticator implements Authenticator{
@Override
public Request authenticate(Route route, Response response) throws IOException {
synchronized (MyAuthenticator.class){
//获取存在本地的token
String currentAuth = getToken();
String newToken = currentAuth;
//对比本次失效的request的的Authorization是否和本地的一致
//若一致,则请求刷新token
//若不一致,则使用最新token再次发出请求
if(currentAuth.equals(response.request().header("Authorization"))){
//同步请求token
newToken = tokenService.refreshToken().exec();
//保存token到本地
saveToken();
//使用新的token再次发起请求
}
return response.request().newBuilder()
.header(AUTHORIZATION, newToken)
.build();
}
}
}
理解
-
当
Authenticator被触发时,必定是服务端返回了401,源码在okhttp的内置interceptor->RetryAndFollowUpInterceptor->followUpRequest(Response userResponse) -
有了上一条逻辑,我们知道当前request的token必定失效,必定要更新一下token之后再次发起,但我们不知道 是因为本地token就已经失效还是并发的原因,其他请求中已经更新了token,但在这里还未感知到
-
所以我们使用同步代码块,在块中判断本次request的token是否与本地存储的相等,之后的详细逻辑已经在注释中