{ "token":"478f71ce-0c34-44a0-a002-d33a4d7a5451", // accessToken "expire":86400, // token过期时间 "refreshToken":"9e6b24ff-34d0-4fd8-847f-4d4842a4b77c" // refreshToken }
1.不需要鉴权的接口,直接访问后端即可,可以通过正则的方式匹配
2.需要鉴权的接口,需要拿到有效的token才能访问后端
3.刷新token接口,需要拿到refreshToken
import axios from 'axios' import router from '../router' import store from '../vuex/store' import * as types from '../vuex/types' import {Loading} from 'element-ui' // 默认超时时间 axios.defaults.timeout = 50000 // 相对路径设置 axios.defaults.baseURL = '' let loading // 开始加载 function startLoading() { loading = Loading.service({ lock: true, text: '加载中...', background: 'rgba(0, 0, 0, 0.2)' }) } // 结束加载 function endLoading() { loading.close() } let needLoadingRequestCount = 0 export function showFullScreenLoading() { if (needLoadingRequestCount === 0) { startLoading() } needLoadingRequestCount++ } export function tryHideFullScreenLoading() { if (needLoadingRequestCount <= 0) return needLoadingRequestCount-- if (needLoadingRequestCount === 0) { endLoading() } } // 是否有请求在刷新token window.isRefreshing = false // 被挂起的请求数组 let subscribesArr = [] // push所有请求到数组中 function subscribeTokenRefresh(cb) { subscribesArr.push(cb) } // 用新token发起请求 function reloadSubscribesArr(token) { subscribesArr.map(cb => cb(token)) } /** * 快过期了 和 已经过期了 * @returns {boolean} */ function isTokenExpired() { let expiredTime = store.state.expirationTime if (expiredTime) { let nowTime = new Date().getTime() let willExpired = (expiredTime - nowTime) / 1000 < 10 * 60 return willExpired } return false } function directLogin() { router.push({ path: '/home', query: { redirectUrl: window.location.href.split('#')[1] || '' } }) } // http request 拦截器 axios.interceptors.request.use( config => { // 设置参数 if (!config.headers['Content-Type']) { config.headers = { 'Content-Type': 'application/json' } } // 如果是不需要token的接口直接返回即可 if (config.url.startsWith('/blog/open') || config.url === '/blog/login') { return config } // 获取token const token = store.state.accessToken // 如果token存在,首先校验是否已经过期,如果已经过期,跳转到登录页面 if (token) { let refreshToken = store.state.refreshToken if (isTokenExpired() && config.url.indexOf('/admin/') > -1) { if (!window.isRefreshing) { window.isRefreshing = true post('/blog/refresh/token', {refreshToken: refreshToken}) .then((res) => { window.isRefreshing = false if (res.code === 200) { const tokenVo = res.data store.dispatch('setTokenInfo', tokenVo) reloadSubscribesArr(tokenVo.token) } else { subscribesArr = [] window.localStorage.clear() directLogin() } }) .catch((err) => { window.isRefreshing = false subscribesArr = [] window.localStorage.clear() directLogin() }) } let retry = new Promise((resolve, reject) => { subscribeTokenRefresh((newToken) => { config.headers.Authorization = `Bearer ${newToken}` resolve(config) }) }) return retry } else { config.headers.Authorization = `Bearer ${token}` return config } } else { directLogin() } // // 鉴权参数 // if (config.method === 'get') { // // get请求下 参数在params中,其他请求在dada中 // config.params = config.params || {} // // let json = JSON.parse(JSON.stringify(config.params)) // // 一些参数处理 // } else { // config.data = config.data || {} // // 一些参数处理 // } showFullScreenLoading() return config }, err => { tryHideFullScreenLoading() return Promise.reject(err) } ) // http response 拦截器 axios.interceptors.response.use( response => { // 统一code处理 if (response.status === 401) { window.localStorage.clear() router.push({ name: '/home', query: { redirectUrl: window.location.href.split('#')[1] || '', is_new_user_url: 1 } }) } else if (response.status === 500) { this.$message.error(response.error) } tryHideFullScreenLoading() return response }, error => { if (error.response) { switch (error.response.status) { case 401: store.commit(types.SET_LOGIN_STATUS, false) store.commit(types.REMOVE_TOKEN_INFO) router.replace({ path: '/home', query: {redirect: router.currentRoute.fullPath} }) } } tryHideFullScreenLoading() return Promise.reject(error.response.data) } ) export function put(url, data = {}) { return new Promise((resolve, reject) => { axios.put(url, data) .then(response => { if (response.status === 200) { resolve(response.data) } else { this.$message.error(response.statusText) } }, err => { reject(err) }) }) } export function post(url, data = {}) { return new Promise((resolve, reject) => { axios.post(url, data) .then(response => { if (response.status === 200) { resolve(response.data) } else { this.$message.error(response.statusText) } }, err => { reject(err) }) }) } export function get(url, data = {}) { return new Promise((resolve, reject) => { axios.get(url, data) .then(response => { if (response.status === 200) { resolve(response.data) } else { this.$message.error(response.statusText) } }, err => { reject(err) }) }) } export function del(url, data = {}) { return new Promise((resolve, reject) => { axios.delete(url, data) .then(response => { if (response.status === 200) { resolve(response.data) } else { this.$message.error(response.statusText) } }, err => { reject(err) }) }) } export function form(url, formData = {}) { let config = { headers: { 'Content-Type': 'multipart/form-data' } } return new Promise((resolve, reject) => { axios.post(url, formData, config) .then(response => { if (response.status === 200) { resolve(response.data) } else { this.$message.error(response.statusText) } }, err => { reject(err) }) }) }
下面是项目具体使用代码:参考https://www.cnblogs.com/ljx20180807/p/9921347.html
//******************************************加入TOKEN let token = localStorage.access_token; if (token) { axios.defaults.headers["Authorization"] = "bearer " + token; } //******************************************处理TOKEN过期问题 let is_refreshing = false; axios.defaults.retry = 10;//设置全局的请求次数 axios.defaults.retryDelay = 800;//请求的间隙 axios.interceptors.response.use(function (response) { return response; }, function (error) { const {config, response: {status, data}} = error; // 如果config不存在或未设置重试选项,请拒绝 if (!config || !config.retry) return Promise.reject(err); // 设置变量跟踪重试次数 config.__retryCount = config.__retryCount || 0; // 检查是否已经达到最大重试总次数 if (config.__retryCount >= config.retry) { //抛出错误信息 return Promise.reject(error); } // 增加请求重试次数 config.__retryCount += 1; //获取最新token if (status == 401) { if (!is_refreshing) { is_refreshing = true; axios.put('api/accounts/refresh_token/' + localStorage.refresh_token).then((d) => { //将标志置为false is_refreshing = false; if (d && d.data) { const json = d.data; if (json.Result == 1 && json.Message == "invalid_grant") { router.replace({path: "/login"}); } else { console.log("重新请求TOEKN"+config.__retryCount); //保存最新信息 token = json.Data.access_token; localStorage.access_token = token; localStorage.refresh_token = json.Data.refresh_token; axios.defaults.headers["Authorization"] = "bearer " + token; } } }).catch(err => { console.log(err); router.replace({path: "/login"}); }); } // 创建新的异步请求 let backoff = new Promise(function (resolve) { setTimeout(function () { console.log("重新请求********" + config.__retryCount); config.headers.Authorization = 'bearer ' + localStorage.access_token; resolve(); }, config.retryDelay || 1); }); // 返回axios信息,重新请求 return backoff.then(function () { console.log("重新请求" + config.__retryCount); config.headers.Authorization = 'bearer ' + localStorage.access_token; return axios(config); }); }else{ return Promise.reject(error); } });