微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

vue的token刷新处理的方法

第一次接触token处理,初来乍到,说错的地方还请各位多多指教。

token身份验证机制

客户端登录请求成功后,服务器将用户信息(如用户id)使用特殊算法加密后作为验证的标志发送给用户(即token),当用户下次发起请求时,会将这个token捎带过来,服务器再将这个token通过解密后进行验证,通过的话,则向客户端返回请求的数据;反之,则请求失败。

token优点

它是无状态的,且服务器不用像传统的身份认证(session)那样需要保存会话信息,减轻了服务器的压力。

vue的token刷新处理

在对token身份验证机制进行一次简单介绍后,进入正文...

一般为了安全性,token都会设置一个过期时间,在过期之后就无法请求相关接口了,这时应该怎么办呢,是直接退出登录吗?

在目前公司的项目里,为了更好的用户体验,我们选择手动刷新token。登录请求成功后,会返回一个token和token过期时间,在每次请求api时,前端可以先判断一下token是否即将过期或已过期,如果是,则请求刷新token的接口,成功替换原来的token之后才可以重新发起请求。

下面,我们直接看代码,这是在vue的请求拦截器里进行的相关操作:

/获取刷新token请求的token/
function getRefreshToken () {
return JSON.parse(localStorage.auth).refresh_token
}

/push所有请求到数组中/
function subscribeTokenRefresh (cb) {
refreshSubscribers.push(cb)
}

/刷新请求(refreshSubscribers数组中的请求得到新的token之后会自执行,用新的token去请求数据)/
function onRrefreshed (token) {
refreshSubscribers.map(cb => cb(token))
}

/请求拦截/
ajax.interceptors.request.use(
config => {
const authTmp = localStorage.auth
/判断是否已登录/
if (authTmp) {
/解析登录信息/
let auth = JSON.parse(authTmp)
/判断auth是否存在/
if (auth) {
/在请求头中添加token类型、token/
config.headers.Authorization = auth.token_type + ' ' + auth.token
/判断刷新token请求的refresh_token是否过期/
if (util.isRefreshTokenExpired()) {
alert('刷新token过期,请重新登录')
/清除本地保存的auth/
localStorage.removeItem('auth')
window.location.href = '#/login'
return
}
/判断token是否将要过期/
if (util.isTokenExpired() && config.url.indexOf('admin/auth/current') === -1) {
/判断是否正在刷新/
if (!window.isRefreshing) {
/将刷新token的标志置为true/
window.isRefreshing = true
/发起刷新token的请求/
apiList.refreshToken({refresh_token: getRefreshToken()}).then(res => {
/将标志置为false/
window.isRefreshing = false
/成功刷新token/
config.headers.Authorization = res.data.data.token_type + ' ' + res.data.data.token
/更新auth/
localStorage.setItem('auth',JSON.stringify(res.data.data))
/执行数组里的函数,重新发起被挂起的请求/
onRrefreshed(res.data.data.token)
/执行onRefreshed函数后清空数组中保存的请求/
refreshSubscribers = []
}).catch(err => {
alert(err.response.data.message)
/清除本地保存的auth/
// localStorage.removeItem('auth')
window.location.href = '#/login'
})
}
/把请求(token)=>{....}都push到一个数组中/
let retry = new Promise((resolve,reject) => {
/(token) => {...}这个函数就是回调函数/
subscribetokenRefresh((token) => {
config.headers.Authorization = 'Bearer ' + token
/将请求挂起/
resolve(config)
})
})
return retry
}
}
return config

} else {
/登录直接返回配置信息/
return config
}
},/错误操作/
err => {
return Promise.reject(err)
}
)

这里需要注意几点:

1、当token即将过期或者已过期时,原则上,我们只需要有一个接口去触发刷新token的请求即可,这里的isRefreshing 变量,就起到这样一个监控的作用,它相当于一把锁,当刷新token的操作被触发后,其他的触发操作就被排斥在外了。

rush:js;"> window.isRefreshing = false

2、刷新token的接口,用到了一个另外的token(refresh_token),这也是出于安全性考虑的,并且它也有过期时间,不过这个过期时间一般都比普通token的过期时间要长,所以在上面代码中,会发现,我在请求拦截中优先判断了refresh_token是否过期,如果过期则直接退出登录,不再进行下一步的操作。

rush:js;"> /*判断刷新token请求的refresh_token是否过期*/ if (util.isRefreshTokenExpired() && config.url.indexOf('admin/auth/current') === -1) { alert('刷新token过期,请重新登录') /*清除本地保存的auth*/ localStorage.removeItem('auth') window.location.href = '#/login' return }

3、在触发了刷新token的操作后,我们还需要先将其他的请求挂起,在获取新的token之后再重新发起这些请求。

{....}都push到一个数组中*/ let retry = new Promise((resolve,reject) => { /*(token) => {...}这个函数就是回调函数*/ subscribetokenRefresh((token) => { config.headers.Authorization = 'Bearer ' + token /*将请求挂起*/ resolve(config) }) }) return retry

在刷新token请求的成功回调里执行下面代码,重新发起请求。

rush:js;"> /*执行数组里的函数,重新发起被挂起的请求*/ onRrefreshed(res.data.data.token)

4、因为有人在评论里问util文件,应该是想知道具体怎么判断token过期的,其实在获得token时,是有返回一个token过期时间 ,你可以先将它先保存起来,然后在需要时,拿出来与本地时间比较即可

rush:js;"> /*判断token是否过期*/ function isTokenExpired() { /*从localStorage中取出token过期时间*/ let expiredTime = new Date(JSON.parse(localStorage.auth).expired_at).getTime() / 1000 /*获取本地时间*/ let NowTime = new Date().getTime() / 1000 /*获取校验时间差*/ let diffTime = JSON.parse(sessionStorage.diffTime) /*校验本地时间*/ NowTime -= diffTime /*如果 < 10分钟,则说明即将过期*/ return (expiredTime - NowTime) < 10*60 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

原文地址:https://www.jb51.cc/vue/31472.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐