vue3-封装AES(CryptoJS)前端加密解密通讯

打印 上一主题 下一主题

主题 1039|帖子 1039|积分 3117

项目场景:

防止数据被爬取,前后端传参吸收参数需要加密处理,使用AES加密。主要使用CryptoJS库中的函数方法,加密:CryptoJS.AES.encrypt(), 解密:CryptoJS.AES.decrypt()。

代码实现


  • 安装CryptoJS库:
  1. npm install crypto-js
复制代码

  • 创建文件夹,@/utils/secret,引入CryptoJS库并封装加密解密函数方法:
  1. import CryptoJS from 'crypto-js/crypto-js';
  2. const key = CryptoJS.enc.Utf8.parse('123321'); // 密钥 后端提供
  3. const iv = CryptoJS.enc.Utf8.parse(''); // 偏移量
  4. /**
  5. * AES加密 :字符串 key iv  返回base64
  6. */
  7. export function Encrypt(word) {
  8.   const srcs = CryptoJS.enc.Utf8.parse(word);
  9.   const encrypted = CryptoJS.AES.encrypt(srcs, key, {
  10.     iv: iv,
  11.     mode: CryptoJS.mode.ECB,
  12.     padding: CryptoJS.pad.Pkcs7,
  13.   });
  14.   return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
  15. }
  16. /**
  17. * AES 解密 :字符串 key iv  返回base64
  18. *  */
  19. export function Decrypt(word) {
  20.   const base64 = CryptoJS.enc.Base64.parse(word);
  21.   const src = CryptoJS.enc.Base64.stringify(base64);
  22.   const decrypt = CryptoJS.AES.decrypt(src, key, {
  23.     iv: iv,
  24.     mode: CryptoJS.mode.ECB,
  25.     padding: CryptoJS.pad.Pkcs7,
  26.   });
  27.   return CryptoJS.enc.Utf8.stringify(decrypt);
  28. }
复制代码

  • 引入加密解密方法,对axios中封装的request 请求前的统一处理做加密:
  1. // 引入
  2. import { Encrypt, Decrypt } from '/@/utils/secret';
  3. this.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
  4.       // If cancel repeat request is turned on, then cancel repeat request is prohibited
  5.       // @ts-ignore
  6.       const { ignoreCancelToken } = config.requestOptions;
  7.       const ignoreCancel =
  8.         ignoreCancelToken !== undefined
  9.           ? ignoreCancelToken
  10.           : this.options.requestOptions?.ignoreCancelToken;
  11.       !ignoreCancel && axiosCanceler.addPending(config);
  12.       if (requestInterceptors && isFunction(requestInterceptors)) {
  13.         config = requestInterceptors(config, this.options);
  14.       }
  15.        // 关键代码:
  16.        // JSON加密,formData不加密(对需要处理的数据格式做判断)
  17.        if (Object.prototype.toString.call(config.data) != '[object FormData]') {
  18.          config.data = { encryptedData: Encrypt(JSON.stringify(config.data)) }; // 加密传参,后端要求的传参:encryptedData:加密参数
  19.        }
  20.       return config;
  21.     }, undefined);
复制代码

  • response 响应前的统一处理做解密:
  1. this.axiosInstance.interceptors.response.use(async (res: AxiosResponse<any>) => {
  2.           // 关键代码:
  3.       // 导出时数据格式为blob不解密(对需要处理的数据格式做判断)
  4.       if (Object.prototype.toString.call(res.data) != '[object Blob]') {
  5.         res.data = JSON.parse(Decrypt(res.data)); // 解密返回参数
  6.       }
  7.       const config = res.config;
  8.       if (res.data.code === 401) {
  9.         // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
  10.         if (!isRefreshToken) {
  11.           isRefreshToken = true;
  12.           // 1. 获取到刷新token
  13.           if (getRefreshToken()) {
  14.             // 2. 进行刷新访问令牌
  15.             try {
  16.               const refreshTokenRes = await this.refreshToken();
  17.               // 2.1 刷新成功,则回放队列的请求 + 当前请求
  18.               setToken('Bearer ' + refreshTokenRes.data.data.accessToken);
  19.               (config as Recordable).headers.Authorization = getToken();
  20.               requestList.forEach((cb: any) => {
  21.                 cb();
  22.               });
  23.               requestList = [];
  24.               return new Promise((resolve) => {
  25.                 resolve(this.axiosInstance(config));
  26.               });
  27.               // res = await Promise.all([this.axiosInstance(config)])[0]
  28.             } catch (e) {
  29.               requestList.forEach((cb: any) => {
  30.                 cb();
  31.               });
  32.             } finally {
  33.               requestList = [];
  34.               isRefreshToken = false;
  35.             }
  36.           }
  37.         } else {
  38.           // 添加到队列,等待刷新获取到新的令牌
  39.           return new Promise((resolve) => {
  40.             requestList.push(() => {
  41.               (config as Recordable).headers.Authorization = getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
  42.               resolve(this.axiosInstance(config));
  43.             });
  44.           });
  45.         }
  46.       }
  47.       res && axiosCanceler.removePending(res.config);
  48.       if (responseInterceptors && isFunction(responseInterceptors)) {
  49.         res = responseInterceptors(res);
  50.       }
  51.       return res;
  52.     }, undefined);
复制代码

终极结果

加密传参:

后端返回参数加密:

在线加密解密工具:https://www.mklab.cn/utils/aes


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

自由的羽毛

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表