const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes,
});
const VueRouterPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(to) {
return VueRouterPush.call(this, to).catch((err) => err);
};
router.beforeEach((to, from, next) => {
const fullPath=to.fullPath.match(/\?(.*)/)
if(fullPath) {
const searchParams = new URLSearchParams(fullPath[1])
if (searchParams.get('key')) {
localStorage.setItem('accessToken', searchParams.get('key'))
next(to.path)
}
}else {
next()
}
})
export default router;
request1.js(和其他request.js不同)中:
引入文件依赖:
//创建axios实例
import axios from "axios";
// 导入 sm-crypto 库
import sm from "sm-crypto";
import CryptoJS from 'crypto-js'
import { jwtDecode } from "jwt-decode";
import { getToken, setToken, removeToken } from "@/utils/auth";
import { Notification, MessageBox, Message, Loading } from "element-ui";
import errorCode from "@/utils/errorCode";
import { eventBus } from '../../src/main';
请求拦截器:
// 请求拦截器
service.interceptors.request.use(
(config) => {
// 在发送请求之前做些什么
let accessToken = localStorage.getItem("accessToken");
// console.log("key", accessToken);
//解码密钥
const jwtSecret = "8w9L95DwBCD9xjkR"; // 生成JWT密钥,固定数值
// 解码JWT令牌获取参数
// clientId secretKey secretValue timeEnd
const decodedToken = jwtDecode(accessToken, jwtSecret);
console.log(decodedToken);
const clientId = decodedToken.clientId; //应用ID
console.log("clientId");
console.log(clientId);
const secretKey = decodedToken.secretKey; //密钥
const secretValue = decodedToken.secretValue; //密钥值
const timeEnd = decodedToken.timeEnd; //获取key有效截止时间的时间戳
const redirectUri = decodedToken.redirectUri ? decodedToken.redirectUri : null;
window.redirectUri = redirectUri;
window.clientId = clientId; // 存储在全局变量中
// 通过事件总线发送事件通知
eventBus.$emit('dataUpdated', {clientId,redirectUri});
console.log("window.clientId");
console.log(window.clientId);
// 检查key是否有效
if (timeEnd && Date.now() > Number(timeEnd)) {
// key已过期,重新开始忘记密码流程
return Promise.reject(); //超时,请求中断
}
const nonce = generateNonce(); // 生成随机字符串nonce
const timestamp = Date.now(); // 获取当前时间戳(毫秒级别)
const sign = generateSign(nonce, timestamp, clientId, secretValue); // 生成签名sign
// 生成加密key
const payload = {
clientId,
timestamp,
nonce,
secretKey,
sign,
};
const jwtToken = generateKey(payload, jwtSecret);
// console.log("key");
// console.log(jwtToken);
config.headers["key"] = jwtToken; // 将key添加到请求头中并转换为字符串类型 // 将key添加到请求头中并转换为字符串类型
return config;
},
(error) => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 生成随机字符串nonce的函数
function generateNonce() {
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const length = 16;
let nonce = "";
for (let i = 0; i < length; i++) {
nonce += characters.charAt(Math.floor(Math.random() * characters.length));
}
return nonce;
}
// 生成签名sign的函数
function generateSign(nonce, timestamp, clientId, secretValue) {
const plaintext = `nonce=${nonce}×tamp=${timestamp}&clientId=${clientId}&secret=${secretValue}`;
const sign = sm.sm3(plaintext); // 使用sm-crypto库中的sm3函数生成签名
return sign;
}
// 函数用于将对象编码为Base64格式
function encodeBase64(obj) {
const stringifiedObj = JSON.stringify(obj);
const wordArray = CryptoJS.enc.Utf8.parse(stringifiedObj);
return CryptoJS.enc.Base64.stringify(wordArray).replace(/=+$/, "");
}
// 生成JWT的函数
function generateJWT(payload, secret) {
// 定义JWT的头部
const header = { alg: "HS256", typ: "JWT" };
// 编码头部和负载
const encodedHeader = encodeBase64(header);
const encodedPayload = encodeBase64(payload);
// 生成签名
const signature = CryptoJS.HmacSHA256(
encodedHeader + "." + encodedPayload,
secret
);
const signatureBase64 = CryptoJS.enc.Base64.stringify(signature).replace(
/=+$/,
""
);
const jwtToken = `${encodedHeader}.${encodedPayload}.${signatureBase64}`;
return jwtToken;
}
// 生成key的函数
function generateKey(payload, jwtSecret) {
const jwtToken = generateJWT(payload, jwtSecret);
return jwtToken;
}
响应拦截器(无特殊处理):
function logOutWay() {
MessageBox.confirm('未登录或登录已过期,请重新登录。', '系统提示', {
confirmButtonText: '重新登录',
showCancelButton: false,
distinguishCancelAndClose: false,
showClose: false,
closeOnClickModal: false,
type: 'warning'
}
).then(() => {
// 跳转到登录页面
let accessTokenKey = getToken()
removeToken()
localStorage.removeItem('accessToken')
window.location.href = process.env.VUE_APP_BASE_JUMP+'auth/logout?accessToken=' + accessTokenKey + '&redirectUri='+process.env.VUE_APP_BASE_JUMP
}).catch(() => {
});
}
// 响应拦截器
service.interceptors.response.use(
(res) => {
const isEncrypt = true;
if (isEncrypt === "true" && !matchs(res.config.url, excludPtahs)) {
//console.log("================解密===================")
res.data = JSON.parse(interfaceDecryptSm2(res.data));
}
// console.log("拦截器===", res);
// 未设置状态码则默认成功状态
const code = res.data.code || 0;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode["default"];
// 二进制数据则直接返回
if (
res.request.responseType === "blob" ||
res.request.responseType === "arraybuffer"
) {
// console.log("1111===");
return res.data;
}
if (code === 401) {
} else if (code === 1) {
if (msg && msg.includes("key不存在或已过期")) {
logOutWay()
// 中断请求
return Promise.reject("无效的会话,或者会话已过期,请重新登录。");
} else {
Message({ message: msg, type: "error" });
return Promise.reject(new Error(msg));
}
} else if (code === 601) {
Message({ message: msg, type: "warning" });
return Promise.reject("error");
}
// else if (code !== 0) {
// Notification.error({ title: msg })
// return Promise.reject('error')
// }
else {
// console.log("22222===",res.data);
return res.data;
}
},
(error) => {
console.log("err====" + error);
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
} else if (message.includes("timeout")) {
message = "系统接口请求超时";
} else if (message.includes("Request failed with status code")) {
if (message.substr(message.length - 3) == 401) {
console.log("401走重新请求token逻辑");
message = "未登录或登录已过期,请重新登录。";
} else {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
}
Message({ message: message, type: "error", duration: 5 * 1000 });
return Promise.reject(error);
}
);
//导入文件
export default service;