token失效前,自动刷新token。
后端逻辑:会同时存在多个token,每个token4小时失效。token失效错误code -1000
方案一:
1、应用启动时,进行判断
wxlogin() {
auth
.checkSession()
.then(() => {
const tokenExpire = Storage.get('tokenExpire') || ''
const dateTime = new Date().getTime()/1000
if (tokenExpire && tokenExpire - dateTime > myConfig.RESTTIME) {
// 未失效,无需登录,直接处理业务
this.navigationFunc()
return
}else {
// token失效时间,距离当前时间是否小于30分钟
// 重新走登录
this.login()
}
})
.catch(() => {
this.login()
})
},
2、请求前进行拦截:
异步刷新token,不阻塞请求业务请求。改阶段token刷新为异步,依然可能会出现接口-1000
// 白名单,登录获取token接口
const WITELIST = ['xxx/xxxx', 'xxx/xxxx1']
/**
*
*请求拦截器
* @param {*} config
*/
async request(config) {
// 添加token
const url = config.url.split('?')[0]
if(!WITELIST.includes(url)) {
const token = Storage.get('token') || ''
if (token) config.header.Authorization = token
// 请求锁 防止多次触发token刷新
if(!isRefreshing) {
isRefreshing = true
this.isRefreshToken()
}
}
}
// 是否需要刷新token
isRefreshToken() {
const tokenExpire = Storage.get('tokenExpire') || ''
const dateTime = new Date().getTime()/1000
// token失效时间,距离当前时间是否小于30分钟
if(tokenExpire && (tokenExpire - dateTime < myConfig.RESTTIME)) {
this.refreshToken()
}
}
3、请求后针对-1000进行拦截:
pendings 存储errcode =-1000的接口,不返回接口请求。 同步去刷新token,待token刷新成功后,遍历pendings并返回请求数据。
let isRefreshing = false // 请求锁
let pendings = [] // 请求队列
const INVALIDTOKENCODE = '-1000'
/**
*响应拦截器
*
* @param {*} result
*/
async response(result, resolve, reject, closeToast, options) {
const { code, msg } = result
if (code == 200) {
resolve(result)
} else if (WHITELIST.indexOf(code) > -1) {
resolve(result)
} else if (code == INVALIDTOKENCODE) {
pendings.push(() => { resolve(Http.base(options)) })
if(!isRefreshing) {
isRefreshing = true
await this.refreshToken()
pendings.map(fun => fun() )
isRefreshing = false
pendings = []
}
方案二:
计时器检测token是否快失效
// onShow 应用启动时也会触发
// 切换到后台时,清掉计时器。返回前台时,添加计时器
onShow: function () {
this.isRefreshToken()
// 每10分钟检测一次
this.interval = setInterval(() => {
this.isRefreshToken()
},10 * 60 * 1000)
},
onHide: function () {
console.log('App Hide')
if(this.interval) {
clearInterval(this.interval)
this.interval = null
}
}
isRefreshToken() {
const tokenExpire = storage.get('tokenExpire') || ''
const dateTime = new Date().getTime()/1000
if(tokenExpire && tokenExpire - dateTime <= 0){
// token,已失效,直接走登录
Navigation.reLaunch('/pages/index/index')
}else if (tokenExpire && tokenExpire - dateTime < config.RESTTIME) {
// 刷新token
this.refreshToken()
}
},