忘记密码找回流程请求拦截器-前端

时间:2024-03-20 15:41:01
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}&timestamp=${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;