说明: 这里的代码可能更新的不及时,查看最新代码 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 的请求参数):
{
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模块发送请求
request(requestParams, function(error, response, body){
// 如果没有问题, 则 body 为服务器返回的数据
console.log(body);
});
ps:如果请求的结果返回 无效的 url, 请检查你的 url, url = host + path ;headers 中也是需要传递 path 参数的。
使用方法:
/*
* @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);
});
核心代码:
/*
* @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 > 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');
}
};
//请求唯一标识,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