> 技术文档 > 教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密

教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密


目录

  • 一、序言
  • 二、Pre-request预请求脚本语法
    • 1、Pre-request脚本简介
    • 2、Postman中的变量
    • 3、Postman中的全局对象
  • 三、Pre-request脚本实现请求参数加密加签
    • 1、引入三方库
    • 2、定义公私钥环境变量
    • 3、预请求脚本实操

一、序言

开发和测试同学平时多少都会用Postman进行后台接口调试,尤其是请求经过网关时,通常数据都需要进行加密传输,以及加签等操作。

这时候需要用到Pre-requestPost-response脚本,这篇文章将会详细介绍关于Postman这些脚本的小细节。


二、Pre-request预请求脚本语法

1、Pre-request脚本简介

通过名字就可以看出来,Pre-request脚本会在请求发送到服务端前执行,如下:
教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密
预请求脚本可以在Collections(集合)、Folder(文件夹)和API接口上定义,如果三者都定义了预请求脚本,那么执行顺序为:Collections > Folder > API接口
教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密

备注:Postman运行环境基于Node.js,因此相关JS语法可以无缝迁移。

2、Postman中的变量

Postman中支持各种作用域变量定义,支持的作用域有Global(全局)、Collection(集合)、Environment(环境变量)、DataLocal(脚本中本地变量),变量访问优先级从内到外,依次递增,如下:

教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密
通过pm内置对象可以访问各作用域的变量,如pm.gloabalpm.environment等等,如下:

// collection var \'score\' = 1// environment var \'score\' = 2// first request runconsole.log(pm.variables.get(\'score\')); // outputs 2console.log(pm.collectionVariables.get(\'score\')); // outputs 1console.log(pm.environment.get(\'score\')); // outputs 2// second request runpm.variables.set(\'score\', 3);// local varconsole.log(pm.variables.get(\'score\')); // outputs 3// third request runconsole.log(pm.variables.get(\'score\')); // outputs 2

备注:通过pm.variables对象获取变量时会根据上图中的优先级从里到外获取。

除此之外,Postman中还内置了一些动态变量,这些动态变量可以通过{{$guid}}花括号进行引用,如下:

教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密
在脚本中可以通过pm.variables.replaceIn()方法进行引用,如下:

const stringWithVars = pm.variables.replaceIn(\"Hi, my name is {{$randomFirstName}}\");console.log(stringWithVars);

3、Postman中的全局对象

Postman中支持常用的Javascript全局对象,可以看到大部分都支持。

教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密
除此之代,Postman还内置了一些三方库,比如moment.jsuuid.js等,使用内置三方库格式如下:

const moment = pm.require(\'moment\');const now = moment().format(\'YYYY-MM-DD HH:mm:ss\');console.log(\"当前时间: \"+ now);

三、Pre-request脚本实现请求参数加密加签

目前前端常见的加解密库有CryptoJSjsencryptjsrsasign,关于如何通过这些库实现对称加解密、非对称加解密&加验签的细节可以参考我之前的两篇文章:

  • 前端CryptoJS和Java后端数据互相加解密(AES)
  • 前后端RSA互相加解密、加签验签、密钥对生成

接下来的例子将以RSA非对称加密和加签为例,通过postman预请求脚本进行操作。

1、引入三方库

这里我使用了jsencryptjsrsasign两个库,首先定义了两个全局变量,变量的值为对应库的js脚本,如下:
教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密
通过全局变量获取到脚本内容后,通过eval()函数动态加载执行,就能获取到相关全局对象。

教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密

备注:这两个库的脚本可直接在https://cdnjs.com/上搜索获取。

2、定义公私钥环境变量

开发、测试环境使用的公私钥都不一样,最好用环境变量进行区分,这里我定义了两个环境变量来存储公钥和私钥,如下:
教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密

备注:前端第三方库要求publicKeyprivateKey的格式为标准pem格式,需要带-----BEGIN PUBLIC KEY-----前缀。

3、预请求脚本实操

这里的预请求脚本可以作用在Collections文件夹或者单个接口上,我一般全局定义在某个Collections上。

脚本内容如下:

/** * RSA加密 */function encryptByRSA(publicKey, plainText) { eval(pm.globals.get(\'jsencrypt\')); const encryptor = new window.JSEncrypt(); encryptor.setPublicKey(publicKey); return encryptor.encrypt(plainText);}/** * RSA SHA256加签 */function signBySHA256WithRSA(privateKey, msg) { eval(pm.globals.get(\'jsrsasign\')); const key = KEYUTIL.getKey(privateKey); const signature = new KJUR.crypto.Signature({ alg: \"SHA256withRSA\", }); signature.init(key); signature.updateString(msg); // 签名后的为16进制字符串,这里转换为16进制字符串 return hextob64(signature.sign());}function sign(data) { // 获取私钥 const privateKey = pm.environment.get(\'privateKey\'); const signatureStr = signBySHA256WithRSA(privateKey, data); console.log(`生成的签名为: ${signatureStr}`) return signatureStr;}function encrypt() { // 获取公钥 const publicKey = pm.environment.get(\'publicKey\'); // 获取请求体 const requestBody = pm.request.body.raw; if (!requestBody) { return; } console.log(\"请求数据:\" + requestBody); try { // 将请求体解析为JSON对象 const jsonData = JSON.parse(requestBody); // 要加密的字段名 (替换为实际需要加密的字段名) const encryptedFields = [\"password\", \"encryptPwd\", \"newEncryptPwd\", \"paymentPin\", \"loginPwd\"]; const filterFields = encryptedFields.filter(v => jsonData[v]); if (!filterFields) { return; } filterFields.forEach(field => { // 加密指定字段 const plainText = jsonData[field]; const encryptedValue = encryptByRSA(publicKey, plainText) console.log(`字段[${field}]加密后的内容为:${encryptedValue}`) // 更新JSON中的值 jsonData[field] = encryptedValue; // 将修改后的JSON转回字符串并更新请求体 pm.request.body.raw = JSON.stringify(jsonData); }) return jsonData; } catch (error) { console.error(\"加密过程发生错误:\", error); }}// 定义全局变量const navigator = {};const window = {};const jsonData = encrypt();

这里需要注意的是,脚本最后为什么要定义navigatorwindow两个全局变量,原因如下:

  • JSEncrypt依赖于windownavigator对象,没有这两对象访问会失败。
  • 前面说过Postman基于Node.js运行,而windownavigator是浏览器特有的对象。

备注:关于pm.request和pm.response等对象的数据结构可参考Postman变量结构说明。

教你在Postman中对请求参数进行加密加签预处理!_postman rsa加密

尚麦网