1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 前端无感刷新token

前端无感刷新token

时间:2020-02-08 09:26:59

相关推荐

前端无感刷新token

单个接口的刷新token很好解决,难点是多接口并发

首先将token过期后的请求存到一个数组队列中,想办法让这个请求处于等待中,一直等到刷新token后再逐个重试清空请求队列。

那么如何做到让这个请求处于等待中呢?为了解决这个问题,我们得借助Promise。将请求存进队列中后,同时返回一个Promise,让这个Promise一直处于Pending状态(即不调用resolve或reject),此时这个请求就会一直等啊等,只要我们不执行resolve或reject,这个请求就会一直在等待。当刷新请求的接口返回来后,我们再调用resolve或reject,逐个重试

基于nuxt框架,$axios模块,伪代码如下:

import { Message, Loading } from "element-ui"import Vue from "vue"export default ({ $axios, store, app, redirect, route, req, res }) => {let [loadingCount, currencyCode, currentLanguage, isRefreshing, token] = [0,"","",true,""]$axios.onError(error => {const code = parseInt(error.response && error.response.status)if (error.response && code === 401) {if (!token) {if (error.response.config.headers.GoLogin) {goLogin()return}return}if (isRefreshing) {// 刷新tokenrefreshToken(error.response.config.headers.GoLogin)}isRefreshing = false// 将请求挂起(返回一个pending状态的promise,等待刷新接口返回结果后,再调用resolve或reject)const retryOriginalRequest = new Promise((resolve, reject) => {addSubscriber(token => {if (!token) {/* eslint-disable */return reject("token refresh error")/* eslint-enable */}if (error.response && token) {const config = error.response.configconfig.headers.Authorization = `Bearer ${token}`$axios.request(config).then(res => {resolve(res)})}})})return retryOriginalRequest}return Promise.reject(error)})async function refreshToken(config) {let host = ""if (process.server) {host = store.state.host || ""} else {host = ""}const data = await $axios.$post(`${host}/account/refresh-token`, {}, { baseURL: "" }).catch(err => {// 清空store里面的用户信息mit("setUser", {})// rejectonAccessTokenFetched("")if (config) {goLogin()}return Promise.reject(err)})let expireIn = ""if (data && data.code === 0) {token = data.data.tokenexpireIn = data.data.expires_inif (process.server) {const stringObject = req.headers.cookiereq.headers.cookie = replaceParamVal(stringObject, "token", token)res.setHeader("Set-Cookie",`token=${token};Domain=.;Path=/;Max-Age=${expireIn}`)}// 刷新token成功,执行数组里的函数,重新发起被挂起的请求(resolve)onAccessTokenFetched(token)} else {// 清空store里面的用户信息mit("setUser", {})// rejectonAccessTokenFetched("")if (config) {goLogin()}}// app.$cookies.set("token", token)isRefreshing = true}// 替换新tokenfunction replaceParamVal(stringObject, paramName, replaceWith) {const str = stringObject.replace(/\s/g, "")/* eslint-disable */const re = eval('/('+ paramName+'=)([^;]*)/gi')/* eslint-enable */const newParam = str.replace(re, paramName + "=" + replaceWith)return newParam}// 被挂起的请求数组let subscribers = []// push所有请求到数组中function addSubscriber(callback) {subscribers.push(callback)}// 刷新请求(subscribers数组中的请求得到新的token之后会自执行,用新的token去请求数据)function onAccessTokenFetched(token) {subscribers.forEach(callback => {callback(token)})subscribers = []}function goLogin() {if (process.server) {redirect(`/account/login`)} else {window.location.href = `/account/login`}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。
相关阅读
无感刷新token方法

无感刷新token方法

2021-06-28

vue无感刷新token

vue无感刷新token

2019-05-21

axios无感刷新token

axios无感刷新token

2018-07-27

实现双token无感刷新

实现双token无感刷新

2020-08-30