阿里云 api 网关签名 sdk-node

说明: 这里的代码可能更新的不及时,查看最新代码 http://git.oschina.net/anziguoer/api-gateway-demo-sign-node

api-gateway-demo-sign-node 阿里 api 网关签名 SDK
step 1 配置 ali_gateway_sign.js

在文件ali_gateway_sign.js中配置自己项目的 KEY 和 SECRET
step 2 配置参数

1>.index.js 文件里面配置 aliGetWaySign 的请求参数

    var options = {
        Method : 'post|get',
        Url : 'http://localhost/path',
        // 参数, 如果有则配置, 没有则不配置
        Form : {
            mabile : '12341234',
            password : 'asdfasdfadf'
        }
    };

    Method, Path 这两个参数名称最好不要更改,如果需要传参数给 api, 你需要传递 Form,格式如上,需要签名。

2>.获取签名, 以及发送请求的参数

    var requestParams = aliGetWaySign(options);

    此处返回的数据是这样子的(正好可以直接发送给 request 的请求参数):

    
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
{
method: 'get',
url: 'http://localhost/path',
form: {
mabile : '12341234',
password : 'asdfasdfadf'
},
headers:
{
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
Accept: 'application/json; charset=UTF-8',
'Content-MD5': '',
Date: 2016-09-29T09:33:05.549Z,
Method: 'get',
'X-Ca-Key': '23423044',
'X-Ca-Nonce': 'fk50xqq4wa3imtk',
'X-Ca-Timestamp': 1475141585549,
'V-App-Client-Information': 'app_name:hxwx|plat:win32|ver:3.3|device:wap|os:node|channel_name:wap|udid:1475141585549|client_ip:192.168.0.1|user-agent:test',
'X-Ca-Signature-Headers': 'X-Ca-Key,X-Ca-Nonce,X-Ca-Stage,X-Ca-Timestamp',
'X-Ca-Stage': 'TEST',
Url: 'http://localhost/path?mabile=12341234&passwordasdfasdfadf',
Path: '/path?mabile=12341234&passwordasdfasdfadf',
'X-Ca-Signature': 'nLHD3apb17LHUjuyA1pjL96W2GIYXoo7I68ql93QfOw='
}
}
3>. request 执行请求 // 使用 node request模块发送请求
1
2
3
4
request(requestParams, function(error, response, body){
// 如果没有问题, 则 body 为服务器返回的数据
console.log(body);
});
ps:如果请求的结果返回 无效的 url, 请检查你的 url, url = host + path ;headers 中也是需要传递 path 参数的。`</pre> <span id="OSC_h3_2"></span> ### 使用方法:
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
/*
* @Author: yulongyang
* @Email: anziguoer@sina.com
* @Date: 2016-09-27 16:34:43
* @Last Modified by: yulongyang
* @Last Modified time: 2016-09-27 16:40:26
* @Descrition : 阿里云 api 网关测试
*/
var request = require('request');
var aliGetWaySign = require('./ali_gateway_sign');

var requestParams = aliGetWaySign({
Method : 'post|get',
Url : 'http://localhost/path',
// 参数, 如果有则配置, 没有则不配置
Form : {
mabile : '12341234',
password : 'asdfasdfadf'
}
});

// 使用 node request模块发送请求
request(requestParams, function(error, response, body){
// 如果没有问题, 则 body 为服务器返回的数据
console.log(body);
});
<span id="OSC_h3_3"></span> ### 核心代码:
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
/*
* @Author: yulongyang
* @Email: anziguoer@sina.com
* @Date: 2016-09-27 16:30:51
* @Last Modified by: anziguoer
* @Last Modified time: 2016-09-29 17:44:47
* @Descrition : 阿里云 api 网关签名
*/
"use strict";
var querystring = require('querystring');
var crypto = require('crypto');
var url = require('url');
// var config = require('../config/index');
// 定义 key 和 secret
const KEY = '';
const SECRET = '';

module.exports = function( requestParams, callBack ){
// Content-Type、Accept、Content-MD5、Date, 这三个是基础的签名字符串, 必须包含
const defaultSignObj = {
'Content-Type' : 'application/x-www-form-urlencoded;charset=UTF-8',
'Accept' : 'application/json; charset=UTF-8',
'Content-MD5' : '',
'Date' : new Date(),
'Method' : 'GET',
// 'X-Ca-Stage' : 'TEST',
'X-Ca-Key': KEY,
'X-Ca-Nonce' : getNonce(),
'X-Ca-Timestamp' : new Date().getTime(),
'V-App-Client-Information' : "app_name:hxwx|plat:win32|ver:3.3|device:wap|os:node|channel_name:wap|udid:"+new Date().getTime()+"|client_ip:192.168.0.1|user-agent:test", //此字段根据自己的 api 的定义选择传递
'X-Ca-Signature-Headers' : 'X-Ca-Key,X-Ca-Nonce,X-Ca-Stage,X-Ca-Timestamp',
};
config.ali_stage ? defaultSignObj['X-Ca-Stage'] = 'TEST' : '',
requestParams = Object.assign(defaultSignObj, requestParams);
var stringToSign = requestParams.Method.toUpperCase()+"\n"+requestParams.Accept+"\n"+requestParams['Content-MD5']+"\n"+requestParams['Content-Type']+"\n"+requestParams.Date+"\n";

// 检查参数签名的定义参数, 获取签名的参数
var signatureHeaders = requestParams['X-Ca-Signature-Headers'].split(',');
if(signatureHeaders.length &gt; 0){
var Headers = {};
signatureHeaders.forEach(function(val, key){
Headers[val] = requestParams[val];
});
// 按照字典对 Key 进行排序
var keys = Object.keys(Headers);
var newKeys = keys.sort();
var newHeaders = {};
newKeys.forEach(function(val, key){
stringToSign += val + ':' +requestParams[val]+"\n";
});
// 如果有参数传递, 测排序后拼接参数
if( requestParams.Form ){
var newForm = {};
// 按照字典对 Key 进行排序
Object.keys(requestParams.Form).sort().forEach(function(bVal, bKey){
newForm[bVal] = requestParams.Form[bVal];
});
// stringToSign += '?'+querystring.stringify(newForm);
// 如果有中文, 则中文不要编码 querystring.stringify 默认会将中文编码,所以使用 querystring.unescape 反编码
// requestParams.Url += '?' + encodeURI(querystring.unescape(querystring.stringify(newForm)));
requestParams.Url += '?' + querystring.unescape(querystring.stringify(newForm));

}
requestParams.Path = url.parse(requestParams.Url).path;
stringToSign += requestParams.Path;
requestParams['X-Ca-Signature'] = getSignature(stringToSign);
delete requestParams.Form;
// 签名后, 发送前,处理中文编码。
requestParams.Path = encodeURI(requestParams.Path);
requestParams.Url = encodeURI(requestParams.Url);
callBack(null, requestParams);
} else {
callBack('X-Ca-Signature-Headers is required');
}
};
1
2
3
4
5
6
7
8
9
10
11
12
//请求唯一标识,15分钟内AppKey+API+Nonce不能重复,与时间戳结合使用才能起到防重放作用
function getNonce(){
return Math.random().toString(36).substr(2, 15);
// 此处如果 nonce 硬编码了, 接口会返回 Nonce used。
}

/**
* 获取签名
*/
function getSignature(stringToSign){
return crypto.createHmac('sha256',SECRET).update(stringToSign, 'utf8').digest('base64');
}

git代码: http://git.oschina.net/anziguoer/api-gateway-demo-sign-node

坚持原创技术分享,您的支持将鼓励我继续创作!
//