多線程網(wǎng)絡(luò)請(qǐng)求中塌碌,Token刷新的核心思路是同步刷新Token舆驶,異步重新請(qǐng)求橱健。
思路很簡(jiǎn)單,但是要保證穩(wěn)定性和性能沙廉,同異步時(shí)機(jī)很重要拘荡。主要有兩點(diǎn)需要注意:
1,正確判斷何時(shí)需要刷新Token(滿足兩個(gè)條件:1撬陵,接口報(bào)錯(cuò)珊皿;2,未進(jìn)行過刷新流程)袱结。
2亮隙,防止過度刷新(對(duì)條件2加鎖)途凫。
3垢夹,雙重驗(yàn)證減少不必要的線程同步。
下面是偽代碼
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而晒,拋出刷新失敗的異常(一般需要重新登錄或者提示授權(quán)失敗)阅畴。
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
}
}