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

fat_shady 2024-06-28 09:33:02 阅读 92

项目场景:

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


代码实现

安装CryptoJS库:

npm install crypto-js

创建文件夹,@/utils/secret,引入CryptoJS库并封装加密解密函数方法:

import CryptoJS from 'crypto-js/crypto-js';

const key = CryptoJS.enc.Utf8.parse('123321'); // 密钥 后端提供

const iv = CryptoJS.enc.Utf8.parse(''); // 偏移量

/**

* AES加密 :字符串 key iv 返回base64

*/

export function Encrypt(word) {

const srcs = CryptoJS.enc.Utf8.parse(word);

const encrypted = CryptoJS.AES.encrypt(srcs, key, {

iv: iv,

mode: CryptoJS.mode.ECB,

padding: CryptoJS.pad.Pkcs7,

});

return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);

}

/**

* AES 解密 :字符串 key iv 返回base64

* */

export function Decrypt(word) {

const base64 = CryptoJS.enc.Base64.parse(word);

const src = CryptoJS.enc.Base64.stringify(base64);

const decrypt = CryptoJS.AES.decrypt(src, key, {

iv: iv,

mode: CryptoJS.mode.ECB,

padding: CryptoJS.pad.Pkcs7,

});

return CryptoJS.enc.Utf8.stringify(decrypt);

}

引入加密解密方法,对axios中封装的request 请求前的统一处理做加密:

// 引入

import { Encrypt, Decrypt } from '/@/utils/secret';

this.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {

// If cancel repeat request is turned on, then cancel repeat request is prohibited

// @ts-ignore

const { ignoreCancelToken } = config.requestOptions;

const ignoreCancel =

ignoreCancelToken !== undefined

? ignoreCancelToken

: this.options.requestOptions?.ignoreCancelToken;

!ignoreCancel && axiosCanceler.addPending(config);

if (requestInterceptors && isFunction(requestInterceptors)) {

config = requestInterceptors(config, this.options);

}

// 关键代码:

// JSON加密,formData不加密(对需要处理的数据格式做判断)

if (Object.prototype.toString.call(config.data) != '[object FormData]') {

config.data = { encryptedData: Encrypt(JSON.stringify(config.data)) }; // 加密传参,后端要求的传参:encryptedData:加密参数

}

return config;

}, undefined);

response 响应前的统一处理做解密:

this.axiosInstance.interceptors.response.use(async (res: AxiosResponse<any>) => {

// 关键代码:

// 导出时数据格式为blob不解密(对需要处理的数据格式做判断)

if (Object.prototype.toString.call(res.data) != '[object Blob]') {

res.data = JSON.parse(Decrypt(res.data)); // 解密返回参数

}

const config = res.config;

if (res.data.code === 401) {

// 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了

if (!isRefreshToken) {

isRefreshToken = true;

// 1. 获取到刷新token

if (getRefreshToken()) {

// 2. 进行刷新访问令牌

try {

const refreshTokenRes = await this.refreshToken();

// 2.1 刷新成功,则回放队列的请求 + 当前请求

setToken('Bearer ' + refreshTokenRes.data.data.accessToken);

(config as Recordable).headers.Authorization = getToken();

requestList.forEach((cb: any) => {

cb();

});

requestList = [];

return new Promise((resolve) => {

resolve(this.axiosInstance(config));

});

// res = await Promise.all([this.axiosInstance(config)])[0]

} catch (e) {

requestList.forEach((cb: any) => {

cb();

});

} finally {

requestList = [];

isRefreshToken = false;

}

}

} else {

// 添加到队列,等待刷新获取到新的令牌

return new Promise((resolve) => {

requestList.push(() => {

(config as Recordable).headers.Authorization = getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改

resolve(this.axiosInstance(config));

});

});

}

}

res && axiosCanceler.removePending(res.config);

if (responseInterceptors && isFunction(responseInterceptors)) {

res = responseInterceptors(res);

}

return res;

}, undefined);


最终效果

加密传参:

在这里插入图片描述

后端返回参数加密:

在这里插入图片描述

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

在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。