-
token:
-
作用:在访问一些接口时,需要传入token,就是它。
-
有效期:2小时(安全)。
-
refresh_token
-
作用: 当token的有效期过了之后,可以使用它去请求一个特殊接口(这个接口也是后端指定的,明确需要传入refresh_token),并返回一个新的token回来(有效期还是2小时),以替换过期的那个token。
-
有效期:14天。(最理想的情况下,一次登陆可以持续14天。)
-
refresh_token工作机制
- 用户在首次完成登录时会分别得到 token 和 refresh_token
- 当 token 失效后(例如2小时之后),调用接口A会返回 401 状态码(这是与后端约定好的规则)
- 检测状态码是否为 401,如果是,则携带refreshToken去调用刷新token的接口
- 刷新 token 的接口后会返回新的 token 和 refreshToken
- 把401的接口A重新发送一遍
refreshToken功能-基本实现
-
正常登录进入my/index
-
在本地存储中直接修改localstorage的token值,模拟token失效。
-
刷新页面,重新发一次请求(此时请务必确保请求拦截器中的token是从本地存储中拿到的)
-
出现401错误
// 响应拦截器 http.intercept.response = async ({ statusCode, data, config }) => { // debugger console.log(statusCode, data, config) // console.log(statusCode) // http 响应状态码 // console.log(config) // 发起请求时的参数 if (data.code === 401) { const app = getApp() // 调用接口获取新的 token const res = await http({ url: '/refreshToken', method: 'POST', header: { Authorization: 'Bearer ' + app.getToken('refreshToken'), } })
app.setToken('token', res.token) app.setToken('refreshToken', res.refreshToken) config = Object.assign(config, { header: { // 更新后的 token Authorization: 'Bearer ' + res.token, }, }) // 重新发请求 return http(config)} // 拦截器处理后的响应结果 if (data.code === 10000) { return data.data } else { wx.$toast(data.message || '请求失败') return Promise.reject(data.message) } }
03.refreshToken也过期的特殊处理
刷新token请求这个接口也可能导致401,若是刷新token接口请求导致的则表明refreshToken也过期了,此时应该跳转到登录页
http.intercept.response = async ({ statusCode, data, config }) => {
// debugger
console.log(statusCode, data, config)
// console.log(statusCode) // http 响应状态码
// console.log(config) // 发起请求时的参数
if (data.code === 401) {
if (config.url.includes('/refreshToken')) {
console.log('/refreshToken过期了')
// 获取当前页面的路径,保证登录成功后能跳回到原来页面
const pageStack = getCurrentPages()
const currentPage = pageStack.pop()
const redirectURL = currentPage.route
// 跳由跳转(登录页面)
wx.redirectTo({
url: '/pages/login/index?redirectURL=/' + redirectURL,
})
return Promise.reject('refreshToken也过期了,就只能重新登录了')
}
const app = getApp()
// 调用接口获取新的 token
const res = await http({
url: '/refreshToken',
method: 'POST',
header: {
Authorization: 'Bearer ' + app.getToken('refreshToken'),
}
})
app.setToken('token', res.token)
app.setToken('refreshToken', res.refreshToken)
config = Object.assign(config, {
header: {
// 更新后的 token
Authorization: 'Bearer ' + res.token,
},
})
// 重新发请求
return http(config)
}
// 拦截器处理后的响应结果
else if (data.code === 10000) {
return data.data
} else {
wx.$toast(data.message || '请求失败')
return Promise.reject(data.message)
}
}