建议阅读对象:已掌握postman的基本使用、了解一丢丢 JavaScript
本地安装的Postman版本: Version 9.15.11
自从项目的接口全部加密了之后,我愁了可长一段时间,因为之前写的接口自动化脚本跑不动了。终于坐不住了,决定必须把这个加解密问题给解决掉。抠了前端加解密的js脚本,花了1天时间总算是调试完成,如今我的自动化用例又可以跑起来了。
注:不同公司、不同项目,加解密的逻辑、方式都是不一样的。以下主要是举例说明在postman中要如何处理加解密,具体代码上肯定不能照搬,要根据实际情况调整。但是,掌握了思路,其他的都是小case啦。
先举个例子说明下某个项目的接口加解密逻辑,不然后面的脚本理解上可能容易产生偏差。
加密前的入参:
{
"data": { ... },
"appid": "###########",
"token": "###########",
"sign": "###########"
}
加密后的入参:
{
"srcdata": { ... },
"appid": "###########",
"token": "###########",
"srcsign": "###########"
}
加密逻辑:
将不含sign、token的加密前入参进行SM3加密,得到加密后sign;
将加密后的srcsign替换掉加密前的sign,将整个入参执行SM4加密,得到加密后的data;
将加密后的srcdata替换掉加密前的data,然后发起请求。
解密逻辑:
将srcdata执行SM4解密,就可以了。
//以上面例子中的加解密逻辑举例说明:
url:测试地址,手动配置到环境变量中,实际接口里采用动态变量形式{{url}}调用,方便切换环境。
token:手动添加到环境变量中,也可以请求 [获取token的接口] 并自动设置为环境变量;(一般是动态的,在处理加密时引用变量更方便)
sign_key:签名key,手动配置到环境变量中(找开发要)
data_key:加密密钥 ,手动配置到环境变量中(找开发要)
srcsign:加密后的签名,在[Pre-request Script]中处理后自动添加到环境变量。每请求一次业务接口,就会自动更新当前值[CURRENT VALUE]。
srcdata:加密后的入参中的data,在 [Pre-request Script] 中处理后自动添加到环境变量。每请求一次业务接口,就会自动更新当前值[CURRENT VALUE]。
1、将加解密算法封装到一个js文件夹里,提供3个函数:签名加密函数、SM4加密函数、SM4解密函数。(如果像我一样不会写代码,让前端同事帮忙写下。毕竟他们有现成的,直接整理到一个文件里就好了)
2、将js文件内的代码直接拷贝到[Pre-request Script]、[Tests]。(如果你看不懂js代码,就不要想着优化了,直接全部复制粘贴就对了。使用的时候直接在后面追加自己的脚本,如:引用函数、断言之类的。)
将已加密的入参复制到[request body],然后将被加密的部分(srcsign、srcdata)以及token改成动态参数,引用环境变量。如下:
{
"appid": "###########",
"token": "{{token}}",
"srcsign": "{{srcsign}}",
"srcdata": "{{srcdata}}"
}
//使用说明:修改reqt_json即可,其他代码不要动
//1、将加密前的入参reqt_json复制粘贴到[Pre-request Script]中
//注意:不含sign、token
reqt_json = {
"data": { ... },
"appid": "###########"
}
//2、获取环境变量中的token,拼接到reqt_json中,作为待加密的签名报文;
token = pm.environment.get("token");
reqt_json.token= token
console.log(reqt_json)
//----------此处为js文件内的代码,就不展示出来啦----------
console.log('------------前置处理:加密开始------------')
//3、环境变量中去读取sign_key
sign_key = pm.environment.get("sign_key");
//引用加密函数,对sing加密
const signData = sign(reqt_json, sign_key)
//将加密后的签名设置为环境变量
pm.environment.set("srcsign", signData);
//4、环境变量中去读取data_key
data_key = pm.environment.get("data_key");
//将加密后的srcsign拼接到reqt_json中,作为待加密的data报文;
reqt_json.srcsign= signData
data = reqt_json
//引用加密函数,对data加密
const encryptSM4Data = encryptSM4(data, data_key)
console.log("加密后的data为:")
console.log(encryptSM4Data)
//将加密后的data设置为环境变量
pm.environment.set("srcdata", encryptSM4Data);
console.log('------------前置处理:加密结束------------')
//到此,入参加密就处理完了。send的时候,会自动先执行预处理脚本,
//然后发起请求时request boy中的变量取环境变量中的值,就可以成功。
//使用说明:去环境变量中修改 加密密钥sign_key、data_key
//----------此处为js文件内的代码,就不展示出来啦----------
console.log('----------------------后置处理:解密开始------------------')
//1、从环境变量中获取加密密钥data_key
data_key = pm.environment.get("data_key");
var JSdata =JSON.parse(responseBody);
//console.log(JSdata.chs_fjs_encdata)
//2、引用[SM4解密函数],得到解密后的data,就是解密后的完整出参啦;
const decdata = decryptSM4(JSdata.chs_fjs_encdata, data_key)
console.log('解密后的data为:')
console.log(decdata)
//3、加个断言,判断下解密后的出参中是否code=0 (以接口的实际标志为准)
if(decdata.code === "0")
{
tests["用例执行成功(code为0)"] = true;
}
else{
tests["用例执行失败:"+responseBody] = false;
}
console.log('----------------------后置处理:解密完成------------------')
//到此,解密就结束啦。不用怀疑,真的就是这样处理而已。
以上,加解密处理脚本就写好了,发送请求后,可以在console面板里查看我们打印出来的 [加密后的data]、[解密后的data] 等信息。大概像下面这样:
如上面的,已经可以达到处理解密了。但是,加解密算法是全部放进[Pre-request Script]、[Tests]中,可维护性差。
弊端:
1、算法代码如果很长,追加自己的脚本时都要下拉到底部,操作不方便;
2、如果算法代码变更了,要每个接口的[Pre-request Script]、[Tests]都去更新。如果接口很多,工作量可见一斑。
优化方案:将加解密算法设置为全局变量,在[Pre-request Script]、[Tests]去获取变量,再通过eval()函数执行相关代码。
console.log('----------------------执行算法代码------------------------------')
//将算法文件存放到全局变量中去(字符串形式),然后获取变量suanfa的值,再通过eval()函数将字符串转换为代码执行
eval(postman.getGlobalVariable("suanfa"));
具体操作可参考:postman引入外部js文件
如有不妥,不吝赐教,感谢!