# RefreshToken机制
# 需求分析
用户token不能设置太长的有效时间,这样可以提高接口部分的安全性。
说明:
- 登录请求/login成功之后会响应token&refreshToken;
- token的过期时间比较短,比如1小时到4小时,refreshToken的过期时间比token要长,比如1天或者7天;
- 用户在登录之后,所有的鉴权的接口带上token;
- 如果token过期,则使用refreshToken进行请求/login/refresh接口,请求新的token;
- 如果refreshToken未过期,则返回新token;
- 如果refreshToken过期,则返回401;
# 创建refreshToken接口
添加src/routes/modules/loginRouter.js
路由:
// refresh
router.post('/refresh', loginController.refresh)
调整登录接口src/api/LoginController.js
:
// 微信登录
async wxLogin (ctx) {
// 1.解密用户信息
const { body } = ctx.request
const { user, code } = body
if (!code) {
ctx.body = {
code: 500,
data: '没有足够参数'
}
return
}
const res = await wxGetUserInfo(user, code)
if (res.errcode === 0) {
// 2.查询数据库 -> 判断用户是否存在
// 3.如果不存在 —> 创建用户
// 4.如果存在 -> 获取用户信息
const tmpUser = await User.findOrCreateByUnionid(res)
// 5.产生token,获取用户的签到状态
const token = generateToken({ _id: tmpUser._id })
const userInfo = await addSign(tmpUser)
ctx.body = {
code: 200,
data: userInfo,
token,
// 新增refreshToken
refreshToken: generateToken({ _id: tmpUser._id }, '7d')
}
} else {
ctx.throw(501, res.errcode === 40163 ? 'code已失效,请刷新后重试' : '获取用户信息失败,请重试')
}
}
// refreshToken
async refresh (ctx) {
ctx.body = {
code: 200,
token: generateToken({ _id: ctx._id }, '60m'),
msg: '获取token成功'
}
}
# 前端页面逻辑
- 错误拦截中,针对 401的情况进行单独处理;
- 返回401之后,使用新的request实例请求refreshToken的接口;
- 请求成功之后,更新本地的token及缓存;
- 使用新的Token重新发发起旧的请求;
# 登录失败后处理缓存
在src/store/index.js
中新增关于清除token及用户信息的actions
:
const actions = {
logout ({ commit }) {
commit('setToken', '')
commit('setUserInfo', {})
commit('setRefreshToken', '')
uni.clearStorage()
}
}
最终测试与效果:
← 消息&热门&个人中心 文章详情 →