feat 自动刷新token
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Message } from 'element-ui';
|
||||
import JSEncrypt from 'jsencrypt'
|
||||
import config from '~/config/app'
|
||||
import { createConsumeToken, clearConsumeToken } from '~/utils/consumeToken'
|
||||
import { createConsumeToken, refreshConsumeToken } from '~/utils/consumeToken'
|
||||
|
||||
const passwordFields = [
|
||||
'password', 'password2', 'password_confirm', 'passwordConfirm',
|
||||
@@ -18,6 +18,7 @@ export default function ({ $axios, redirect, app, store }, inject) {
|
||||
requestConfig.headers = requestConfig.headers || {}
|
||||
requestConfig.headers.token = requestConfig.headers.token || store.state.token
|
||||
if (
|
||||
!requestConfig._consumeTokenRetry &&
|
||||
requestConfig.data &&
|
||||
passwordFields.some(field => typeof requestConfig.data[field] === 'string' && requestConfig.data[field])
|
||||
) {
|
||||
@@ -46,14 +47,22 @@ export default function ({ $axios, redirect, app, store }, inject) {
|
||||
}
|
||||
return requestConfig
|
||||
})
|
||||
$axios.onResponse((response) => {
|
||||
$axios.onResponse(async (response) => {
|
||||
const {
|
||||
code,
|
||||
show,
|
||||
msg
|
||||
} = response.data;
|
||||
if (code == 0 && response.data.data && response.data.data.error === 'consume_token_invalid') {
|
||||
clearConsumeToken()
|
||||
const requestConfig = response.config || {}
|
||||
const headers = requestConfig.headers || {}
|
||||
const failedToken = headers['X-Consume-Token'] || ''
|
||||
if (!requestConfig._consumeTokenRetry) {
|
||||
requestConfig._consumeTokenRetry = true
|
||||
await refreshConsumeToken(headers.token || store.state.token, failedToken)
|
||||
return $axios.request(requestConfig)
|
||||
}
|
||||
return response
|
||||
}
|
||||
if (code == 0 && show && msg) {
|
||||
Message({
|
||||
|
||||
@@ -32,6 +32,11 @@ export async function createConsumeToken(loginToken) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function refreshConsumeToken(loginToken, failedToken) {
|
||||
clearConsumeToken(failedToken)
|
||||
return createConsumeToken(loginToken)
|
||||
}
|
||||
|
||||
async function issue(loginToken) {
|
||||
const host = String(config.baseUrl || '').replace(/\/$/, '')
|
||||
if (!host && typeof process !== 'undefined' && process.server) {
|
||||
@@ -57,10 +62,14 @@ async function issue(loginToken) {
|
||||
return token
|
||||
}
|
||||
|
||||
export function clearConsumeToken() {
|
||||
export function clearConsumeToken(expectedToken) {
|
||||
if (expectedToken && cachedToken !== expectedToken) {
|
||||
return false
|
||||
}
|
||||
cachedToken = ''
|
||||
cachedLoginToken = ''
|
||||
refreshAt = 0
|
||||
return true
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
|
||||
@@ -101,9 +101,9 @@ class Login
|
||||
{
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => '消费Token无效或已过期',
|
||||
'msg' => '',
|
||||
'data' => ['error' => 'consume_token_invalid'],
|
||||
'show' => 1,
|
||||
'show' => 0,
|
||||
'time' => 0,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,8 @@
|
||||
var response = {
|
||||
data: res.data,
|
||||
statusCode: res.statusCode,
|
||||
header: res.header
|
||||
header: res.header,
|
||||
config: config
|
||||
};
|
||||
|
||||
if (!validateStatus || validateStatus(res.statusCode)) {
|
||||
@@ -409,7 +410,7 @@
|
||||
var config = Object.create(null); // 创建空对象,作为最终的合并结果
|
||||
// 1.常规属性,如果用户配置了就用用户配置的,如果用户没配置,则用默认配置的;
|
||||
|
||||
var defaultToUserConfig = ["baseURL", "transformRequest", "transformResponse", "paramsSerializer", "timeout", "withCredentials", "adapter", "responseType", "xsrfCookieName", "xsrfHeaderName", "onUploadProgress", "onDownloadProgress", "maxContentLength", "validateStatus", "maxRedirects", "httpAgent", "httpsAgent", "cancelToken", "socketPath"];
|
||||
var defaultToUserConfig = ["baseURL", "transformRequest", "transformResponse", "paramsSerializer", "timeout", "withCredentials", "adapter", "responseType", "xsrfCookieName", "xsrfHeaderName", "onUploadProgress", "onDownloadProgress", "maxContentLength", "validateStatus", "maxRedirects", "httpAgent", "httpsAgent", "cancelToken", "socketPath", "_consumeTokenRetry"];
|
||||
defaultToUserConfig.forEach(function (prop) {
|
||||
userConfig = userConfig || {}; // 如果用户配置里有
|
||||
|
||||
|
||||
@@ -33,6 +33,11 @@ export async function createConsumeToken(loginToken) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function refreshConsumeToken(loginToken, failedToken) {
|
||||
clearConsumeToken(failedToken)
|
||||
return createConsumeToken(loginToken)
|
||||
}
|
||||
|
||||
function issue(loginToken) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const host = String(baseURL || '').replace(/\/$/, '')
|
||||
@@ -68,10 +73,14 @@ function issue(loginToken) {
|
||||
})
|
||||
}
|
||||
|
||||
export function clearConsumeToken() {
|
||||
export function clearConsumeToken(expectedToken) {
|
||||
if (expectedToken && cachedToken !== expectedToken) {
|
||||
return false
|
||||
}
|
||||
cachedToken = ''
|
||||
cachedLoginToken = ''
|
||||
refreshAt = 0
|
||||
return true
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import axios from '../js_sdk/xtshadow-axios/axios.min'
|
||||
import axios from '../js_sdk/xtshadow-axios/axios'
|
||||
import JSEncrypt from 'jsencrypt'
|
||||
import store from '../store'
|
||||
import { paramsToStr, currentPage, tabbarList, acountList } from './tools'
|
||||
@@ -6,7 +6,7 @@ import Cache from './cache'
|
||||
import { TOKEN, BACK_URL } from '../config/cachekey'
|
||||
import { baseURL } from '../config/app'
|
||||
import { getWxCode, toLogin, wxMnpLogin } from './login'
|
||||
import { createConsumeToken, clearConsumeToken } from './consumeToken'
|
||||
import { createConsumeToken, refreshConsumeToken } from './consumeToken'
|
||||
|
||||
const passwordFields = [
|
||||
'password', 'password2', 'password_confirm', 'passwordConfirm',
|
||||
@@ -41,6 +41,7 @@ service.interceptors.request.use(
|
||||
config.data = checkParams(config.data)
|
||||
config.params = checkParams(config.params)
|
||||
if (
|
||||
!config._consumeTokenRetry &&
|
||||
config.data &&
|
||||
passwordFields.some((field) => typeof config.data[field] === 'string' && config.data[field])
|
||||
) {
|
||||
@@ -64,7 +65,7 @@ service.interceptors.request.use(
|
||||
data.password_key_id = response.data.key_id || response.data.keyId
|
||||
config.data = data
|
||||
}
|
||||
if (config.method == 'GET') {
|
||||
if (config.method == 'GET' && !config._consumeTokenRetry) {
|
||||
config.url += paramsToStr(config.params)
|
||||
}
|
||||
config.header = config.header || {}
|
||||
@@ -88,7 +89,15 @@ service.interceptors.response.use(
|
||||
const { code, show, msg, data } = response.data
|
||||
const { route, options } = currentPage()
|
||||
if (code == 0 && data && data.error === 'consume_token_invalid') {
|
||||
clearConsumeToken()
|
||||
const config = response.config || {}
|
||||
const header = config.header || {}
|
||||
const failedToken = header['X-Consume-Token'] || ''
|
||||
if (!config._consumeTokenRetry) {
|
||||
config._consumeTokenRetry = true
|
||||
await refreshConsumeToken(header.token || Cache.get(TOKEN), failedToken)
|
||||
return service(config)
|
||||
}
|
||||
return Promise.resolve(response.data)
|
||||
}
|
||||
if (code == 0 && show && msg) {
|
||||
uni.showToast({
|
||||
|
||||
Reference in New Issue
Block a user