赞
踩
这两天做项目,第一次做了刷新token的功能。
以前做的最多的是:用户登录,给一个固定的token,并且这个token有一个期限。如果该token过期。那么持有该token的用户再次发起请求时,将会收到拒绝,并且前端页面给出“您的登录已过期”的提示,并跳转至登录页面。用户只能重新输入账号密码进行登录,然后再继续进行刚刚的操作。
我们可以看到,不由分说地将已过期的用户退出登录,是不科学和不人性化的。那么如何做才能比较好的进行token的管理呢?
我们引入refresh_token
,可以比较好的解决这个问题。
首先明确一个前提:access_token
和refresh_token
两者都各自有一个期限,
我们假设access_token
的期限是1小时,refresh_token
的期限是2小时。
当access_token
过期后,我们不会像之前一样,直接让该用户退出登录。而是转而判断该用户的refresh_token
的期限是否也过期。
如果refresh_token
也过期了,那么该用户即可退出登录。
如果没有过期,此时应再次发起一个刷新access_token
和refresh_token
的请求,该请求会返回2个新的token,2个新token又各自有1个小时和2个小时的期限。
我们前端在拿到新的access_token
和refresh_token
后,重新将存在cooies
中的2个token进行更新,并使用新的access_token
再次发起刚刚失败的请求。这样在用户没有感知的情况下,将用户的token进行了“更新换代”的操作。
比较核心的代码如下(vue项目,使用ElementUI):
// 重新获取token 并将未完成的请求继续完成
async function doRequest (error) {
const data = await store.dispatch('user/refreshToken')
if (data) {
const { access_token } = data
const config = error.response.config
config.headers.Authorization = 'Bearer ' + access_token
const res = await axios.request(config)
return res
}
}
// token过期后 刷新token refreshToken({ commit }) { return new Promise((resolve, reject) => { const params = { grant_type: 'refresh_token', refresh_token: getRefreshToken() } axios({ url: `${baseUrl}auth/oauth/token`, method: 'post', params: params, headers: { isToken: false, Authorization: 'Basic b2E6MQ==' } }).then(res => { const { data } = res commit('SET_TOKEN', data.access_token) commit('SET_REFRESH_TOKEN', data.refresh_token) setToken(data.access_token) setRefreshToken(data.refresh_token) resolve(data) }).catch(error => { MessageBox.alert('请重新登录!', '登录已过期', { confirmButtonText: '确定', type: 'warning', callback: action => { store.dispatch('user/resetToken').then(() => { location.reload() }) } }) reject(error) }) }) },
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。