在POSTMAN工具中
请求URL:
{{open-api.root}}/open-gateway/api/address/sonAddress?custId=JSST_SHOPPING_OPEN&signValidate=on&sign={{sign}}
请求体:
{
"head": {
"reqTime": {{reqTime}},
"reqSerial": {{reqSerial}},
"ver": "1.0",
"custId": "JSST_SHOPPING_OPEN"
},
"body": {
"code": "320000"
}
}
在Postman的Envionments标签中设置以下变量。其实也可以设置为局部变量。
reqSerial
reqTime
sign
签名的逻辑如下:
- 请求地址栏中需要以下请求参数:?signValidate={[on|off|}&custId={custId}&sign={sign}&other=xxx
- custId是开放平台为三方平台分配,同时分配#{接入密钥}。
- partA = 请求地址栏中除sign参数以外,以参数名的ASCII升序排列,将其对应的参数键值以key1=value1&拼接,如参数值为空不参与。
- partB = custId对应的#{接入密钥}。
- partC = 请求体报文(如遇回车等,请原样保留)。
- sign的签名:MD5(partA + partB + partC, UTF8)的十六进制小写字符串
在Postman的《Pre-request Script》标签中设置以下脚本:
/* 设置请求时间 */
var moment = require("moment");
var ymdhmis = moment().format("YYYYMMDDHHmmss");
pm.environment.set("reqTime", ymdhmis);
/* 设置请求流水号 */
function randomCoding(){
let number= "";
var n = 5;
for(var i=0;i<n;i++){
number+= Math.floor(Math.random() * 10);
}
return number;
}
var randomNum5 = randomCoding();
var reqSerial = ymdhmis + randomNum5;
pm.environment.set("reqSerial", reqSerial);
/* 设置签名 */
//请求参数
var reqParams = {};
//GET
if(pm.request.url.query instanceof Object){
pm.request.url.query.each(function(obj){
if(obj.disabled === undefined) reqParams[obj.key] = obj.value;
});
}
//POST
if(pm.request.body.formdata instanceof Object){
pm.request.body.formdata.each(function(obj){
if(obj.disabled === undefined) reqParams[obj.key] = obj.value;
});
}
//console.log("reqParams:" + JSON.stringify(reqParams));
//请求参数名按照ASCII码升序排序
var sortParams = [];
for(var key in reqParams){
if(key == "sign" || key === ""){
continue;
}
if(key != "sign") sortParams.push(key);
}
sortParams.sort();
//console.log("sortParams:" + sortParams);
//拼接待签名字符串
var strTmp = [];
for (var p = 0; p < sortParams.length; p++) {
var key = sortParams[p];
var value = pm.request.url.query.get(key);
if(value.indexOf("{{") != -1) {
value = pm.environment.get(value.replace(new RegExp('(\{|\})', "g"),""));
}
value = value ? value : "";
if(value === ""){
continue;
}
strTmp.push(value);
}
var paramValueAppend = strTmp.join("");
console.log("paramValueAppend:" + paramValueAppend);
// 请求体字符串
var reqBody = pm.request.body.raw;
// console.log("reqBody replace before:\n" + reqBody);
reqBody = reqBody.replace(new RegExp('(\{\{reqTime\}\})', "g"),pm.environment.get("reqTime"));
reqBody = reqBody.replace(new RegExp('(\{\{reqSerial\}\})', "g"),pm.environment.get("reqSerial"));
console.log("reqBody replace after:\n" + reqBody);
pm.request.body.raw = reqBody;
var source = paramValueAppend + pm.globals.get("appSecret") + reqBody;// 请求参数 + 密钥 + 请求体
console.log("appSecret:" + pm.globals.get("appSecret"));
console.log("source:" + source);
var md5 = CryptoJS.MD5(source).toString(CryptoJS.enc.Hex);
console.log("md5:" + md5);
pm.environment.unset("sign");
pm.environment.set("sign", md5);
在其控制台调试,你会发现:
reqBody replace after:
{
"head": {
"reqTime": 20211103144040,
"reqSerial": 2021110314404032048,
"ver": "1.0",
"custId": "JSST_SHOPPING_OPEN"
},
"body": {
"code": "320000"
}
}
POST http://open.beta.xxx.com/open-gateway/api/address/sonAddress?custId=JSST_SHOPPING_OPEN&signValidate=on&sign=63329c66ee5cbe1fd3be8b3cefa94c80
如果想知道Java代码如何实现,请参考《服务端统一报文签名》