多线程网络请求中,Token刷新的核心思路是同步刷新Token,异步重新请求。
思路很简单,但是要保证稳定性和性能,同异步时机很重要。主要有两点需要注意:
1,正确判断何时需要刷新Token(满足两个条件:1,接口报错;2,未进行过刷新流程)。
2,防止过度刷新(对条件2加锁)。
3,双重验证减少不必要的线程同步。
下面是伪代码
internal class RefreshTokenInterceptor : Interceptor {
private val lock = Any()
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
var response = chain.proceed(request)
if (接口告知token失效) {
if (tokenProvider.accessToken.isNotEmpty() && tokenProvider.accessToken == request.header("keyForToken")) {
synchronized(lock) {
if (tokenProvider.accessToken.isNotEmpty() && tokenProvider.accessToken == request.header("keyForToken")) {
//刷新Token。刷新成功,更新Token;刷新失败,清空Token,抛出刷新失败的异常(一般需要重新登录或者提示授权失败)。
parseResponse(chain.proceed(newRefreshRequest(request)))
}
}
}
if (tokenProvider.accessToken.isNotEmpty() && tokenProvider.accessToken != request.header("keyForToken"))
response = chain.proceed(request.newBuilder().header("keyForToken", tokenProvider.accessToken).build())
else throw RefreshTokenFailedException
}
return response
}
}