import { options } from '@/http/config.js'; import Request from '@/utils/luch-request/index.js'; const http = new Request(options); import store from "@/store" http.interceptors.request.use((config) => { // 可使用async await 做异步操作 // 假设有token值需要在头部需要携带 let token = uni.getStorageSync('token'); if (token) { config.header['Authorization'] = 'Bearer ' + token; const jwt = decryptJWT(token); const exp = getJWTDate(jwt.exp); // token 已经过期 if (new Date() >= exp) { let refreshToken = store.state.refreshToken; // 携带刷新 token if (refreshToken) { config.header["X-" + 'Authorization'] = 'Bearer ' + refreshToken; } } } // #ifndef H5 let url = config.url if (process.env.NODE_ENV == 'development' && !url.startsWith("http")) { config.url = url } // #endif return config }, config => { // 可使用async await 做异步操作 return Promise.reject(config) }) http.interceptors.response.use((response) => { checkAndStoreAuthentication(response) // 服务端返回的状态码不等于200,则reject() if (response.data.code && response.data.code !== 200) { setTimeout(() => { uni.showToast({ title: response.data.msg, icon: 'none' }); }) if (response.data.code == 401) { const pages = getCurrentPages() const currentPage = pages[pages.length - 1] store.dispatch('clearToken') uni.redirectTo({ url: `/pages/login?redirect=/${currentPage.route}` }) } return Promise.reject(response); } return response.data; }, (response) => { /* 对响应错误做点什么 (statusCode !== 200)*/ setTimeout(() => { uni.showToast({ title: response.data.msg || response.data.error_description || '网络错误', icon: 'none' }); }) return Promise.reject(response) }) /** * @description 解密 JWT token 的信息 * @param token jwt token 字符串 * @returns object */ function decryptJWT(token) { token = token.replace(/_/g, "/").replace(/-/g, "+"); const json = decodeURIComponent(escape(window.atob(token.split(".")[1]))); return JSON.parse(json); } /** * @description 将 JWT 时间戳转换成 Date,主要针对 `exp`,`iat`,`nbf` * @param timestamp 时间戳 * @returns Date 对象 */ function getJWTDate(timestamp) { return new Date(timestamp * 1000); } /** * 检查并存储授权信息 * @param res 响应对象 */ const checkAndStoreAuthentication = (res) => { // 读取响应报文头 token 信息 let token = res.header['access-token']; let refreshToken = res.header['x-access-token']; // 判断是否是无效 token if (token === "invalid_token") { store.dispatch('clearToken') } // 判断是否存在刷新 token,如果存在则存储在本地 else if (refreshToken && token && token !== "invalid_token") { store.dispatch('setToken',{token,refreshToken}) } } export default http;