فهرست منبع

add 新增 请求加密传输 合并优化 !pr377

疯狂的狮子Li 1 سال پیش
والد
کامیت
d0d67b90bc
5فایلهای تغییر یافته به همراه62 افزوده شده و 2 حذف شده
  1. 2 0
      package.json
  2. 2 1
      src/api/login.ts
  3. 45 0
      src/utils/crypto.ts
  4. 2 1
      src/utils/jsencrypt.ts
  5. 11 0
      src/utils/request.ts

+ 2 - 0
package.json

@@ -29,6 +29,7 @@
     "fuse.js": "6.6.2",
     "js-cookie": "3.0.1",
     "jsencrypt": "3.3.1",
+    "crypto-js": "^4.1.1",
     "nprogress": "0.2.0",
     "path-browserify": "1.0.1",
     "path-to-regexp": "6.2.0",
@@ -42,6 +43,7 @@
   "devDependencies": {
     "@iconify/json": "^2.2.40",
     "@intlify/unplugin-vue-i18n": "0.8.2",
+    "@types/crypto-js": "^4.1.1",
     "@types/file-saver": "2.0.5",
     "@types/js-cookie": "3.0.3",
     "@types/node": "18.14.2",

+ 2 - 1
src/api/login.ts

@@ -19,7 +19,8 @@ export function login(data: LoginData): AxiosPromise<LoginResult> {
   return request({
     url: '/auth/login',
     headers: {
-      isToken: false
+      isToken: false,
+      isEncrypt: true
     },
     method: 'post',
     data: params

+ 45 - 0
src/utils/crypto.ts

@@ -0,0 +1,45 @@
+import CryptoJS from 'crypto-js';
+
+/**
+ * 随机生成32位的字符串
+ * @returns {string}
+ */
+const generateRandomString = () => {
+  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+  let result = '';
+  const charactersLength = characters.length;
+  for (let i = 0; i < 32; i++) {
+    result += characters.charAt(Math.floor(Math.random() * charactersLength));
+  }
+  return result;
+};
+
+/**
+ * 随机生成aes 密钥
+ * @returns {string}
+ */
+export const generateAesKey = () => {
+  return CryptoJS.enc.Utf8.parse(generateRandomString());
+};
+
+/**
+ * 随机生成aes 密钥
+ * @returns {string}
+ */
+export const encryptBase64 = (str: string) => {
+  return CryptoJS.enc.Base64.stringify(str);
+};
+
+/**
+ * 使用密钥对数据进行加密
+ * @param message
+ * @param aesKey
+ * @returns {string}
+ */
+export const encryptWithAes = (message: string, aesKey: CryptoJS.lib.WordArray) => {
+  const encrypted = CryptoJS.AES.encrypt(message, aesKey, {
+    mode: CryptoJS.mode.ECB,
+    padding: CryptoJS.pad.Pkcs7
+  });
+  return encrypted.toString();
+};

+ 2 - 1
src/utils/jsencrypt.ts

@@ -2,7 +2,8 @@ import JSEncrypt from 'jsencrypt';
 // 密钥对生成 http://web.chacuo.net/netrsakeypair
 
 const publicKey =
-  'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==';
+  'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
+  'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==';
 
 const privateKey =
   'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +

+ 11 - 0
src/utils/request.ts

@@ -8,6 +8,8 @@ import { errorCode } from '@/utils/errorCode';
 import { LoadingInstance } from 'element-plus/es/components/loading/src/loading';
 import FileSaver from 'file-saver';
 import { getLanguage } from '@/lang';
+import { encryptBase64, encryptWithAes, generateAesKey } from '@/utils/crypto';
+import { encrypt } from '@/utils/jsencrypt';
 
 let downloadLoadingInstance: LoadingInstance;
 // 是否显示重新登录
@@ -29,6 +31,8 @@ service.interceptors.request.use(
     const isToken = (config.headers || {}).isToken === false;
     // 是否需要防止数据重复提交
     const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
+    // 是否需要加密
+    const isEncrypt = (config.headers || {}).isEncrypt === 'true';
     if (getToken() && !isToken) {
       config.headers['Authorization'] = 'Bearer ' + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
     }
@@ -63,6 +67,13 @@ service.interceptors.request.use(
         }
       }
     }
+    // 当开启参数加密
+    if (isEncrypt && (config.method === 'post' || config.method === 'put')) {
+      // 生成一个 AES 密钥
+      const aesKey = generateAesKey();
+      config.headers['encrypt-key'] = encrypt(encryptBase64(aesKey));
+      config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey);
+    }
     // FormData数据去请求头Content-Type
     if (config.data instanceof FormData) {
       delete config.headers['Content-Type'];