阿里云内容安全 API 签名机制

阿里云内容安全 API 没有提供 Node.js 版的 SDK,可以参考一下第三方的 SDK 代码。


HMAC-SHA1签名流程(默认)


1.序列化请求头。

按照以下方式,将所有以x-acs-开头的HTTP头拼接成字符串:

抽取所有以x-acs-开头的HTTP头。

对抽取出来的头按字典顺序排序。

对每个HTTP头,按"HTTP头名称" + ":" + "HTTP头值" + "\n"拼接。


2.序列化URI和query参数。

按照uri + "?clientInfo=" + "ClientInfo的JSON字符串"方式拼接URI和clientInfo参数。

说明 此处不需要URL编码。


3.构建完整的待签名字符串。

按照以下方式,构建完整的待签名字符串:

"POST\napplication/json\n" + 
"HTTP头Content-MD5的值" + "\n" + 
"application/json" + "\n" + 
"HTTP头Date的值" + "\n" + 
"序列化请求头" + "\n" 
"序列化uri和query参数"


以下是一个完整的调用图片同步检测接口的待签名字符串示例:

POST
application/json
C+5Y0crpO4sYgC2DNjycug==
application/json
Tue, 14 Mar 2017 06:29:50 GMT
x-acs-signature-method:HMAC-SHA1
x-acs-signature-nonce:339497c2-d91f-4c17-a0a3-1192ee9e2202
x-acs-signature-version:1.0
x-acs-version:2018-05-09
/green/image/scan?clientInfo={"ip":"127.xxx.xxx.2","userId":"12023xxxx","userNick":"Mike","userType":"others"}


4. 生成签名。

a.对步骤3中得到的字符串,使用AccessKey Secret进行HMAC-SHA1算法加密得到bytes数组。

说明 这一步不要对bytes数组做任何其他处理。

b.对HMAC-SHA1加密得到的bytes数组进行base64编码。

c.将base64编码后的结果放到HTTP头Authorization中的signature:"acs" + " " + AccessKeyId + ":" + signature。

说明 acs和AccessKeyId中间有空格。


5.代码实现

green-nodejs-invoker.js

var http = require('http');
var crypto = require('crypto');
var uuidV1 = require('uuid/v1');

var greenNodejs = function(bizCfg, callback){
	var accessKeyId = bizCfg['accessKeyId'];
	var accessKeySecret = bizCfg['accessKeySecret'];
	var path = bizCfg['path'];
	var clientInfo = bizCfg['clientInfo'];
	var requestBody = bizCfg['requestBody'];
	var greenVersion = bizCfg['greenVersion'];
	var hostname = bizCfg['hostname'];
    var gmtCreate = new Date().toUTCString();
    var md5 = crypto.createHash('md5');
	// 请求头
	var requestHeaders = {
		'Accept':'application/json',
	    'Content-Type':'application/json',  
	    'Content-MD5':md5.update(requestBody).digest().toString('base64'),
	    'Date':gmtCreate,
	    'x-acs-version':greenVersion,
	    'x-acs-signature-nonce':uuidV1(),
	    'x-acs-signature-version':'1.0',
	    'x-acs-signature-method':'HMAC-SHA1'
	};

	// 对请求的签名
	signature(requestHeaders, bizCfg);

	// HTTP请求设置
	var options = {
	    hostname: hostname,
	    port: 80,
	    path: encodeURI(path + '?clientInfo=' + JSON.stringify(clientInfo)),
	    method: 'POST',
	    headers:requestHeaders
	};

	var req = http.request(options, function(res) {
	  res.setEncoding('utf8');
	  res.on('data', function (chunk) {
	  	callback(chunk);
	  });
	});


	req.write(requestBody); 
	req.end();  
}

function signature(requestHeaders, bizCfg){
	var accessKeyId = bizCfg['accessKeyId'];
	var accessKeySecret = bizCfg['accessKeySecret'];
	var path = bizCfg['path'];
	var clientInfo = bizCfg['clientInfo'];
	var signature = [];
	signature.push('POST\n');
	signature.push('application/json\n');
	signature.push(requestHeaders['Content-MD5'] + '\n');
	signature.push('application/json\n');
	signature.push(requestHeaders['Date'] + '\n');
	signature.push('x-acs-signature-method:HMAC-SHA1\n');
	signature.push('x-acs-signature-nonce:' + requestHeaders['x-acs-signature-nonce'] + '\n');
	signature.push('x-acs-signature-version:1.0\n');
	signature.push('x-acs-version:2017-01-12\n');
	signature.push(path + '?clientInfo=' + JSON.stringify(clientInfo));

	var authorization = crypto.createHmac('sha1', accessKeySecret)
                   .update(signature.join(''))
                   .digest().toString('base64');

	requestHeaders.Authorization = 'acs ' + accessKeyId + ':' + authorization;
}

module.exports = greenNodejs;


使用方法:

var uuidV1 = require('uuid/v1');
var greenNodejs = require('./green-nodejs-invoker.js');

const accessKeyId = '<your accessKeyId>';
const accessKeySecret = '<your accessKeySecret>';
const greenVersion = '2017-01-12';
var hostname = 'green.cn-shanghai.aliyuncs.com';
var path = '/green/image/scan';

var clientInfo = {
	"ip":"127.0.0.1"
};

// 请求体,根据需要调用相应的算法
var requestBody = JSON.stringify({  
    bizType:'Green',
    scenes:['porn'],
    tasks:[{
    	'dataId':uuidV1(),
    	'url':'https://xxx.png'
    }]
}); 

var bizCfg = {
	'accessKeyId' : accessKeyId,
	'accessKeySecret' : accessKeySecret,
	'path' : path,
	'clientInfo' : clientInfo,
	'requestBody' : requestBody,
	'hostname' : hostname,
	'greenVersion' : greenVersion
}

greenNodejs(bizCfg, execute);

// 业务代码,根据不同算法的返回结果采取相应的业务流程
function execute(chunk){
	console.log('BODY: ' + chunk);
}


注意,此功能需要阿里云账户的企业认证,才能开通服务。

参考:

https://help.aliyun.com/document_detail/53415.html

https://help.aliyun.com/document_detail/434034.html

修改时间 2024-03-05

声明:本站所有文章和图片,如无特殊说明,均为原创发布。商业转载请联系作者获得授权,非商业转载请注明出处。
真诚赞赏,手留余香
赞赏
随机推荐
Wordpress 主样式表(style.css)
Rollup 教程
MySQL 的 sql_mode 模式介绍:为什么 MySQL 中 int,float,double 类型字段插入空字符时自动转为0
选择排序
使用 MySQL 线程池对压力测试的影响
WordPress 调用自定义头像
WordPress 上传附件
WordPress 增强编辑器功能