项目场景:
防止数据被爬取,前后端传参吸收参数需要加密处理,使用AES加密。主要使用CryptoJS库中的函数方法,加密:CryptoJS.AES.encrypt(), 解密:CryptoJS.AES.decrypt()。
代码实现
- 创建文件夹,@/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);
复制代码- 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
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |