Commit b7edaf3cd8815508f6c7c9567be201dda3a8c726
1 parent
e1a46b79
fix: refresh token after token overdue
Showing
3 changed files
with
96 additions
and
9 deletions
| @@ -14,7 +14,7 @@ const GLOBAL_TOKEN = (() => { | @@ -14,7 +14,7 @@ const GLOBAL_TOKEN = (() => { | ||
| 14 | const common = ls.get(GLOBAL_STORAGE_KEY) | 14 | const common = ls.get(GLOBAL_STORAGE_KEY) |
| 15 | return { | 15 | return { |
| 16 | token: common && common.JWT_TOKEN && common.JWT_TOKEN.value, | 16 | token: common && common.JWT_TOKEN && common.JWT_TOKEN.value, |
| 17 | - refreshToken: common && common.JWT_TOKEN && common.JWT_TOKEN.value, | 17 | + refreshToken: common && common.REFRESH_TOKEN && common.REFRESH_TOKEN.value, |
| 18 | } | 18 | } |
| 19 | })() | 19 | })() |
| 20 | 20 |
| @@ -56,7 +56,7 @@ const createStorage = ( | @@ -56,7 +56,7 @@ const createStorage = ( | ||
| 56 | timeout = null, | 56 | timeout = null, |
| 57 | hasEncrypt = !isDEV, | 57 | hasEncrypt = !isDEV, |
| 58 | } = {}) => { | 58 | } = {}) => { |
| 59 | - if (hasEncrypt && [ key.length, iv.length ].some((item) => item !== 16)) { | 59 | + if (hasEncrypt && [key.length, iv.length].some((item) => item !== 16)) { |
| 60 | throw new Error('When hasEncrypt is true, the key or iv must be 16 bits!'); | 60 | throw new Error('When hasEncrypt is true, the key or iv must be 16 bits!'); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| @@ -86,7 +86,7 @@ const createStorage = ( | @@ -86,7 +86,7 @@ const createStorage = ( | ||
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | getKey(key) { | 88 | getKey(key) { |
| 89 | - return `${ this.prefixKey }${ key }`.toUpperCase(); | 89 | + return `${this.prefixKey}${key}`.toUpperCase(); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | /** | 92 | /** |
| @@ -110,6 +110,19 @@ const createStorage = ( | @@ -110,6 +110,19 @@ const createStorage = ( | ||
| 110 | this.storage.setItem(this.getKey(key), stringifyValue); | 110 | this.storage.setItem(this.getKey(key), stringifyValue); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | + generatorValue(key, value, expire = timeout) { | ||
| 114 | + const stringData = { | ||
| 115 | + value, | ||
| 116 | + time: Date.now(), | ||
| 117 | + expire: !isNullOrUnDef(expire) ? new Date().getTime() + expire * 1000 : null, | ||
| 118 | + }; | ||
| 119 | + const stringifyValue = this.hasEncrypt | ||
| 120 | + ? this.encryption.encryptByAES(stringData) | ||
| 121 | + : stringData; | ||
| 122 | + | ||
| 123 | + return stringifyValue | ||
| 124 | + } | ||
| 125 | + | ||
| 113 | /** | 126 | /** |
| 114 | *Read cache | 127 | *Read cache |
| 115 | * @param {string} key | 128 | * @param {string} key |
| @@ -117,17 +130,20 @@ const createStorage = ( | @@ -117,17 +130,20 @@ const createStorage = ( | ||
| 117 | * @memberof Cache | 130 | * @memberof Cache |
| 118 | */ | 131 | */ |
| 119 | get(key, def = null) { | 132 | get(key, def = null) { |
| 133 | + console.log(this.getKey(key)) | ||
| 120 | const val = this.storage.getItem(this.getKey(key)); | 134 | const val = this.storage.getItem(this.getKey(key)); |
| 121 | if (!val) return def; | 135 | if (!val) return def; |
| 122 | 136 | ||
| 123 | try { | 137 | try { |
| 124 | const decVal = this.hasEncrypt ? this.encryption.decryptByAES(val) : val; | 138 | const decVal = this.hasEncrypt ? this.encryption.decryptByAES(val) : val; |
| 125 | const data = JSON.parse(decVal); | 139 | const data = JSON.parse(decVal); |
| 140 | + console.log(data) | ||
| 126 | const { value, expire } = data; | 141 | const { value, expire } = data; |
| 127 | - if (isNullOrUnDef(expire) || expire >= new Date().getTime()) { | ||
| 128 | - return value; | ||
| 129 | - } | ||
| 130 | - this.remove(key); | 142 | + // if (isNullOrUnDef(expire) || expire >= new Date().getTime()) { |
| 143 | + // return value; | ||
| 144 | + // } | ||
| 145 | + return value | ||
| 146 | + // this.remove(key); | ||
| 131 | } catch (e) { | 147 | } catch (e) { |
| 132 | return def; | 148 | return def; |
| 133 | } | 149 | } |
| @@ -150,4 +166,4 @@ const createStorage = ( | @@ -150,4 +166,4 @@ const createStorage = ( | ||
| 150 | } | 166 | } |
| 151 | }; | 167 | }; |
| 152 | return new WebStorage(); | 168 | return new WebStorage(); |
| 153 | -} | ||
| 169 | +} |
| 1 | +let requestQueue = [] | ||
| 2 | + | ||
| 3 | +const JWT_TOKEN_KEY = 'JWT_TOKEN'; | ||
| 4 | +const REFRESH_TOKEN_KEY = 'REFRESH_TOKEN'; | ||
| 1 | /** | 5 | /** |
| 2 | * custom http request | 6 | * custom http request |
| 3 | */ | 7 | */ |
| @@ -16,7 +20,11 @@ function createAxios(options) { | @@ -16,7 +20,11 @@ function createAxios(options) { | ||
| 16 | 20 | ||
| 17 | instance.interceptors.request.use((config) => { | 21 | instance.interceptors.request.use((config) => { |
| 18 | config.headers["X-Authorization"] = "Bearer " + GLOBAL_TOKEN.token | 22 | config.headers["X-Authorization"] = "Bearer " + GLOBAL_TOKEN.token |
| 23 | + | ||
| 19 | return config | 24 | return config |
| 25 | + }, (error) => { | ||
| 26 | + console.log(error) | ||
| 27 | + return error | ||
| 20 | }) | 28 | }) |
| 21 | 29 | ||
| 22 | /** | 30 | /** |
| @@ -28,10 +36,73 @@ function createAxios(options) { | @@ -28,10 +36,73 @@ function createAxios(options) { | ||
| 28 | }, | 36 | }, |
| 29 | function (error) { | 37 | function (error) { |
| 30 | if (error.response.status == 401) { | 38 | if (error.response.status == 401) { |
| 31 | - layer.alert('登录超时,请重新登录'); | 39 | + // layer.alert('登录超时,请重新登录'); |
| 40 | + // const config = error.config | ||
| 41 | + // const url = config.url | ||
| 42 | + // const method = config.method | ||
| 43 | + // const data = config.data | ||
| 44 | + // const flag = requestQueue.find(item => item.url === url) | ||
| 45 | + // if (!flag) { | ||
| 46 | + // console.log(url, method, data) | ||
| 47 | + // requestQueue.push({ url, method, data }) | ||
| 48 | + // } | ||
| 49 | + | ||
| 50 | + doRefreshToken() | ||
| 32 | } | 51 | } |
| 33 | return Promise.reject(error); | 52 | return Promise.reject(error); |
| 34 | } | 53 | } |
| 35 | ); | 54 | ); |
| 36 | return instance; | 55 | return instance; |
| 37 | } | 56 | } |
| 57 | + | ||
| 58 | + | ||
| 59 | +/** | ||
| 60 | + * @description refresh token | ||
| 61 | + * @param {} params | ||
| 62 | + * @returns | ||
| 63 | + */ | ||
| 64 | +function doRefreshToken(params) { | ||
| 65 | + const refreshToken = GLOBAL_TOKEN.refreshToken | ||
| 66 | + console.log(GLOBAL_TOKEN) | ||
| 67 | + return new Promise((resolve, reject) => { | ||
| 68 | + axios.post('/api/auth/token', | ||
| 69 | + { refreshToken }, | ||
| 70 | + { | ||
| 71 | + headers: { | ||
| 72 | + "content-type": "application/json; charset=UTF-8", | ||
| 73 | + "X-Authorization": "Bearer " + GLOBAL_TOKEN.token, | ||
| 74 | + }, | ||
| 75 | + }) | ||
| 76 | + .then(res => { | ||
| 77 | + | ||
| 78 | + // 存储token | ||
| 79 | + const { refreshToken, token } = res.data | ||
| 80 | + Object.assign(GLOBAL_TOKEN, { refreshToken, token }) | ||
| 81 | + const ls = createStorage({ storage: localStorage }) | ||
| 82 | + const originData = ls.get(GLOBAL_STORAGE_KEY) | ||
| 83 | + const newRefreshToken = ls.generatorValue(REFRESH_TOKEN_KEY, refreshToken, true) | ||
| 84 | + const newToken = ls.generatorValue(REFRESH_TOKEN_KEY, token, true) | ||
| 85 | + console.log(Object.assign(originData, { [REFRESH_TOKEN_KEY]: newRefreshToken, [JWT_TOKEN_KEY]: newToken })) | ||
| 86 | + ls.set(GLOBAL_STORAGE_KEY, Object.assign(originData, { [REFRESH_TOKEN_KEY]: newRefreshToken, [JWT_TOKEN_KEY]: newToken }), true) | ||
| 87 | + | ||
| 88 | + // try { | ||
| 89 | + // requestQueue.forEach(item => { | ||
| 90 | + // const { method, url, data } = item | ||
| 91 | + // console.log({ item }) | ||
| 92 | + // defHttp[method](url, data) | ||
| 93 | + // }) | ||
| 94 | + // requestQueue = [] | ||
| 95 | + // } catch (error) { | ||
| 96 | + | ||
| 97 | + // } | ||
| 98 | + | ||
| 99 | + window.location.reload() | ||
| 100 | + resolve() | ||
| 101 | + }) | ||
| 102 | + .catch((error) => { | ||
| 103 | + const { origin } = window.location | ||
| 104 | + window.location.href = `${origin}/login` | ||
| 105 | + reject(error) | ||
| 106 | + }) | ||
| 107 | + }) | ||
| 108 | +} |