1、引入crypto-js库
npm install crypto-js
2、封装加解密方法(CBC模式)
2.1 将以下方法封装到新文件中,命名为crypto.js
const CryptoJS = require('crypto-js');
// AES密钥
const aesKey = "3v@23$!22@09wT*02$CcaU@$ZsdXSp7&";
const aesIv = "ABCDEFGH12345678";
// 密钥转换为Utf8编码的字节数组
const key = CryptoJS.enc.Utf8.parse(aesKey);
const iv = CryptoJS.enc.Utf8.parse(aesIv);
/**
* AES-CBC 加密
* @param {string} data 要加密的数据
* @returns {string} Base64 编码的密文
*/
function encryptData(data) {
const encrypted = CryptoJS.AES.encrypt(data, key, {
mode: CryptoJS.mode.CBC,
iv: iv,
padding: CryptoJS.pad.Pkcs7
});
// 返回包含IV和密文的对象
const combined = iv.clone().concat(encrypted.ciphertext);
return CryptoJS.enc.Base64.stringify(combined);
}
/**
* AES-CBC 解密
* @param {string} encryptedData Base64 编码的密文
* @returns {string} 解密后的明文
*/
function decryptData(encryptedData) {
const combined = CryptoJS.enc.Base64.parse(encryptedData);
const iv = CryptoJS.lib.WordArray.create(combined.words.slice(0, 4));
const ciphertext = CryptoJS.lib.WordArray.create(combined.words.slice(4));
const decrypted = CryptoJS.AES.decrypt({ ciphertext: ciphertext }, key, {
mode: CryptoJS.mode.CBC,
iv: iv,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
export {
encryptData,
decryptData
}
2.2 在request.js 文件中引入
import {encryptData} from '@/utils/crypto'
3、使用
import axios from 'axios'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import { BASEURL } from '@/utils/config'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi";
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
import {encryptData} from '@/utils/crypto'
let downloadLoadingInstance;
// 是否显示重新登录
export let isRelogin = { show: false };
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: BASEURL,
// 超时
timeout: 100000
})
// request拦截器
service.interceptors.request.use(config => {
// console.log(config,'config')
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
const encryptedData = encodeURIComponent(encryptData(JSON.stringify(config.params)));
config.url = config.url + '?data=' + encryptedData;
config.params = {};
}
// 这里针对登陆接口/sys/loginAdmin没有走加密操作单独处理,暂时保留isRepeatSubmit字段的功能
if ((!isRepeatSubmit || config.url==='/sys/loginAdmin') && (config.method === 'post' || config.method === 'put')) {
if (config.headers['Content-Type'] && config.headers['Content-Type'].includes('application/json')) {
config.data = { data: encryptData(JSON.stringify(config.data)) };
}
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
if (requestSize >= limitSize) {
console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。')
return config;
}
const sessionObj = cache.session.getJSON('sessionObj')
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
cache.session.setJSON('sessionObj', requestObj)
} else {
const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
// const message = '数据正在处理,请勿重复提交';
// console.warn(`[${s_url}]: ` + message)
// return Promise.reject(new Error(message))
} else {
cache.session.setJSON('sessionObj', requestObj)
}
}
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
export default service