如何设置通过Postman实现API网关的请求签名与调试

前言
Postman是一个非常强大的HTTP发包测试工具, 目前Postman已经提供了Windows/Mac/Linux系统的客户端的下载,使用很方便。不过API网关的调试,需要对HTTP请求进行签名才能调用,无法使用简单的curl等发包工具完成,但我们可以使用Postman工具提供的Pre-request Script脚本来实现API网关的签名功能,实现API的调试功能,本文主要介绍如何使用Postman调试API网关接口。

核心代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
var appKey = "<YOUR APP KEY>";
var appSecret = "<YOUR APP SECRET>";

var md5 = calcMd5();
var date = new Date().toString();
var nonce = createUuid();

var textToSign = "";
textToSign += request.method + "\n";
textToSign += request.headers["accept"] + "\n";
textToSign += md5 + "\n";
textToSign += request.headers["content-type"] + "\n";
textToSign += date + "\n";

var headers = headersToSign();
var signatureHeaders;
var sortedKeys = Array.from(headers.keys()).sort()
for (var headerName of sortedKeys) {
textToSign += headerName + ":" + headers.get(headerName) + "\n";
signatureHeaders = signatureHeaders ? signatureHeaders + "," + headerName : headerName;
}
textToSign += urlToSign();
console.log("textToSign\n" + textToSign.replace(/\n/g, "#"));
var hash = CryptoJS.HmacSHA256(textToSign, appSecret)
console.log("hash:" + hash)
var signature = hash.toString(CryptoJS.enc.Base64)
console.log("signature:" + signature)

pm.globals.set('AppKey', appKey);
pm.globals.set('Md5', md5);
pm.globals.set("Date", date);
pm.globals.set("Signature", signature);
pm.globals.set("SignatureHeaders", signatureHeaders);
pm.globals.set("Nonce", nonce);

function headersToSign() {
var headers = new Map();
for (var name in request.headers) {
name = name.toLowerCase();
if (!name.startsWith('x-ca-')) {
continue;
}
if (name === "x-ca-signature" || name === "x-ca-signature-headers" || name == "x-ca-key" || name === 'x-ca-nonce') {
continue;
}
var value = request.headers[name];
headers.set(name, value);
}
headers.set('x-ca-key', appKey);
headers.set('x-ca-nonce', nonce);
return headers;
}

function urlToSign() {
var params = new Map();
var contentType = request.headers["content-type"];
if (contentType && contentType.startsWith('application/x-www-form-urlencoded')) {
const formParams = request.data.split("&");
formParams.forEach((p) => {
const ss = p.split('=');
params.set(ss[0], ss[1]);
})
}
const ss = request.url.split('?');
if (ss.length > 1 && ss[1]) {
const queryParams = ss[1].split('&');
queryParams.forEach((p) => {
const ss = p.split('=');
params.set(ss[0], ss[1]);
})
}

var sortedKeys = Array.from(params.keys())
sortedKeys.sort();

var l1 = ss[0].lastIndexOf('/');
var url = ss[0].substring(l1);
var first = true;
var qs
for (var k of sortedKeys) {
var s = k + "=" + params.get(k);
qs = qs ? qs + "&" + s : s;
console.log("key=" + k + " value=" + params.get(k));
}
return qs ? url + "?" + qs : url;
}

function calcMd5() {
var contentType = request.headers["content-type"];
if (request.data && !contentType.startsWith('application/x-www-form-urlencoded')) {
var data = request.data;
var md5 = CryptoJS.MD5(data);
var md5String = md5.toString(CryptoJS.enc.Base64);
console.log("data:" + data + "\nmd5:" + md5String);
return md5String;
} else {
return "";
}
}

function createUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

0%