js-对请求参数加密

1. 代码

使用的库 cryptojs

/*
	import.meta.env.VITE_KEY: 自定义密钥
*/

// 加密 - 加密单个字段
export const addPassword = (str: string) => {
  const message = cryptojs.enc.Utf8.parse(str)
  const secretPassphrase = cryptojs.enc.Utf8.parse(import.meta.env.VITE_KEY)
  const iv = cryptojs.enc.Utf8.parse(import.meta.env.VITE_KEY)
  return cryptojs.AES.encrypt(message, secretPassphrase, {
    mode: cryptojs.mode.CBC,
    padding: cryptojs.pad.Pkcs7,
    iv
  }).toString()
}

// 解密 - 解密单个字段
export const passPassword = (passStr: string) => {
  const secretPassphrase = cryptojs.enc.Utf8.parse(import.meta.env.VITE_KEY)
  const iv = cryptojs.enc.Utf8.parse(import.meta.env.VITE_KEY)
  return cryptojs.AES.decrypt(passStr, secretPassphrase, {
    mode: cryptojs.mode.CBC,
    padding: cryptojs.pad.Pkcs7,
    iv
  }).toString(cryptojs.enc.Utf8)
}

// 加密 - 加密参数对象
export const addPasswordParams = (obj: any) => {
  const vObject: { [key: string]: any } = {}
  for (let key in obj) {
    const k = addPassword(key)
    if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
      vObject[k] = addPasswordParams(obj[key])
    } else if (Array.isArray(obj[key])) {
      vObject[k] = obj[key].map((item: any) => {
        if (item instanceof Object) {
          return addPasswordParams(item)
        }
        return addPassword(item)
      })
    } else {
      vObject[k] = addPassword(obj[key])
    }
  }
  return vObject
}

// 解密 - 解密参数对象
export const passPasswordParams = (obj: any) => {
  const vObject: { [key: string]: any } = {}
  for (let key in obj) {
    const k = passPassword(key)
    if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
      vObject[k] = passPasswordParams(obj[key])
    } else if (Array.isArray(obj[key])) {
      vObject[k] = obj[key].map((item: any) => {
        if (item instanceof Object) {
          return passPasswordParams(item)
        }
        return passPassword(item)
      })
    } else {
      vObject[k] = passPassword(obj[key])
    }
  }
  return vObject
}

2. 前端

参考 web-fetch封装, 添加

props.body = JSON.stringify(addPasswordParams(JSON.parse(props.body as string)))
// 请求
async request(url: string, props: RequestInit & { headers?: controlType }) {
  props.body = JSON.stringify(addPasswordParams(JSON.parse(props.body as string)))
  const newURL = this.joinUrl(url)
  this.beforeFetch(newURL, props)
  try {
    let response: any
    if (props.headers?.file === 'true') {
      response = await (await fetch(newURL, props)).blob()
    } else {
      response = await (await fetch(newURL, props)).json()
    }
    return this.afterFetch(response, props)
  } catch (e: any) {
    return {
      status: 1000,
      message: e.message
    }
  }
}

3. nodeJs

这里的相关函数的 key 改为了函数参数传入,其他不变。

在前置中间件中添加

req.params = passPasswordParams(paramSecretKey, req.params)
req.body = passPasswordParams(paramSecretKey, req.body)
req.query = passPasswordParams(paramSecretKey, req.query)

前置中间件示例:

// 前置中间件
app.use((req, res, next) => {
  let checkPermission = false
  // 校验一下有没有调用权限
  checkPermission = checkHeaders(req.headers)
  if (!checkPermission) {
    res.send({
      message: '没有调用权限',
      showMessage: true,
      messageType: messageTypes.error,
      data: {},
      status: 401
    })
    return
  }
  // 数据解析
  req.params = passPasswordParams(paramSecretKey, req.params)
  req.body = passPasswordParams(paramSecretKey, req.body)
  req.query = passPasswordParams(paramSecretKey, req.query)
  // 错误中间件
  res.error = (message, showMessage = true, messageType = messageTypes.error, status = 500) => {
    res.send({
      message,
      showMessage,
      messageType,
      data: {},
      status
    })
    return
  }
  // 挂载 加密 模块 生成密文
  res.bcryptjs = bcryptjs
  // 挂载 签名 秘钥 token密钥
  res.tokenSecretKey = tokenSecretKey
  // 挂载 签名 秘钥 token密钥
  res.dataSecretKey = dataSecretKey
  // 挂载 签名 秘钥 token密钥
  res.paramSecretKey = paramSecretKey
  // 挂载 签名 模块 生成token
  res.jwt = jwt
  // 挂载 解析 模块 解析token
  res.expressjwt = expressjwt
  // 加密参数 - 单个
  res.addPasswordParam = (str) => addPasswordParam(paramSecretKey, str)
  // 加密参数 - 对象
  res.addPasswordParams = (obj) => addPasswordParams(paramSecretKey, obj)
  // 解密参数 - 单个
  res.passPasswordParam = (str) => passPasswordParam(paramSecretKey, str)
  // 解密参数 - 对象
  res.passPasswordParams = (obj) => passPasswordParams(paramSecretKey, obj)
  next()
})

4. 效果

// 加密
const add = addPasswordParams({
  pageNumber: 1,
  pageSize: 10,
  tabName: 'today'
})

// add 的值:
{
  "A5UU4ICRCMMn06IvrGtLww==": "9qlNjjqyprYHxzKf0IG8qg==",
  "AOSS2snSNFdcJFziGdxatQ==": "r7oub6PUU0yHRPnXqeDXOw==",
  "199edTursmIsrF9az/hSwA==": "9qlNjjqyprYHxzKf0IG8qg=="
}

// 解密
const pass = passPasswordParams({
  "A5UU4ICRCMMn06IvrGtLww==": "9qlNjjqyprYHxzKf0IG8qg==",
  "AOSS2snSNFdcJFziGdxatQ==": "r7oub6PUU0yHRPnXqeDXOw==",
  "199edTursmIsrF9az/hSwA==": "9qlNjjqyprYHxzKf0IG8qg=="
})

// pass 的值:
{
  pageNumber: '1',
  pageSize: '10',
  tabName: 'today'
}

注意上面解密后 数字变成了字符串, 需要做处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值