基于sm-crypto的sm4的请求/响应与加/解密
有时候需要对项目的请求和返回值进行加密请求,因而笔者使用了sm4
,读者也可以使用别的库如md5
封装加解密:
// ciphertext.js const sm4 = require('sm-crypto').sm4 // 此为密文key,非常重要 export const CIPHERTEXT = `wzdxcskwzdxcskwzdxcskwzdxcskwzdxcsk` //我真的想吃烧烤我真的想吃烧烤我真的想吃烧烤我真的想吃烧烤 /** * 参考: * https://github.com/JuneAndGreen/sm-crypto#sm4 * * */ // 数据加密 用于axios请求拦截器 export const encryptSm4 = ( requestParams = '' )=>{ if (!requestParams) return return sm4.encrypt(requestParams, CIPHERTEXT) } // 数据解密 用于axios相应拦截器 export const decryptSm4 = ( result = '' )=>{ if (!result) return return sm4.decrypt(result, CIPHERTEXT) }
响应/请求拦截中使用加解密方法,以下只写要改动的,其余的可以不变
// request.js import axios from "axios"; import store from "../store"; import { encryptSm4, decryptSm4 } from "./ciphertext"; //生成axios实例 const service = axios.create({ // axios默认统一数据 timeout: 120000, //指定请求超时的毫秒数(0 表示无超时时间) // baseURL:xxxx, //可能有不同类型的api地址,可以在这里设置baseurl,后续中用以对比是否源于指定的url // 如果要校验请求类型,就需要先在这里声明`content-type` headers: { "Content-Type": "application/json" // 设置默认json格式以规避在拦截器中拿不到 content-type问题 } }); // 确认config配置项 const configCheck = (conf, type) => { // 此处可根据需要自定义校验 const isPost = conf.method.toUpperCase() === `POST`; // 是否post // const jsonReg = /application\/json/; // 正则表达式匹配'application/json' // const isJSON = jsonReg.test(conf.headers[`Content-Type`]) // 是否JSON const isFromBaseURL = conf.baseURL.includes(process.env.VUE_APP_BASE_API); //是否基于baseurl // console.log('isFromBaseURL :>> ', conf.baseURL, isFromBaseURL); // console.log('process.env.VUE_APP_BASE_API :>> ', process.env.VUE_APP_BASE_API); return { send: [isFromBaseURL, isPost], receive: [isFromBaseURL] }[type].every(v => v); }; // 请求拦截配置 /** * 有以下方可进行加密: * configCheck 为true * 明确`store`中`encryption`为1 后端控制是否需要将请求/响应加密 */ service.interceptors.request.use(config=>{ ...other code... const isEncrypted = store.encryption === 1 if (isEncrypted && configCheck(config, `send`)) { try { const reqData = encryptSm4(JSON.stringify(config[`data`])); config[`data`] = reqData ? reqData : config[`data`]; } catch (error) { console.log("error :>> ", error); } } ...other code... return config }) // 响应拦截 service.interceptors.response.use(response=>{ let res = response.data; // 这里故意用了`let` 因为加密态下可能要改 // ---------------------- 此处为解密校验 const isEncrypted = store.encryption === 1 // 加密态下返回的只有一堆加密str,因而没有`res.cdoe`属性 if (!res.code && configCheck(response.config, `receive`) && isEncrypted) { try { // 解析加密数据 res = JSON.parse(decryptSm4(res)); if (typeof res === `string`) { console.log(`--------------------`); console.log("res :解析失败返回值>> ", res); console.log("失败接口路径为 :>> ", response.config.url); console.log("接口方法为 :>> ", response.config.method); console.log(`--------------------`); } // 解密后数据不一定是正常返回值,因而这里做了简单校验 if (res.code && Number(res.code) !== 200) { Message({ message: res.msg || "当前网络繁忙,请稍后重试!", type: "error", duration: 3 * 1000 }); return Promise.reject( new Error(res.msg || "当前网络繁忙,请稍后重试") ); } } catch (error) { console.log(`--------------------`); console.log("error :>解析异常告警> ", error); console.log("res :解析失败返回值>> ", res); console.log("失败接口路径为 :>> ", response.config.url); console.log("接口方法为 :>> ", response.config.method); console.log(`--------------------`); } } // 👆----------------------------------- 此处为解密校验 // 接下来可以写正常明文校验,不表 return res })
几点要求:
-
ciphertext.js
的CIPHERTEXT
是每次前后端交互时加解密的依据,必须要前后端统一 -
一个标准加密态下的请求/返回,在控制台中的入参&出参回显应该是一堆乱码,可以以此来判断是否使用了密文
加密态下的入参:
加密态下的出参:
以上。
分类:
vue
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人