Windows Azure的:使用设置的NodeJS一滴CORS性能 [英] windows azure : set blob CORS properties using NodeJS
问题描述
REST API已在2月成立的blob <一个被释放href=\"http://blogs.msdn.com/b/windowsazurestorage/archive/2014/02/03/windows-azure-storage-introducing-cors.aspx\"相对=nofollow> CORS财产,但这并没有为实施的NodeJS还。
REST API has been released in february to set blob CORS property, but this hasn't been implemented for NodeJS yet.
因为我需要这个功能,我想实现它在一个模块中为我的蔚蓝的网站上运行的NodeJS。
Since I need this feature, I tried to implement it in a module for my azure website running NodeJS.
根据REST API文档改变CORS性能和来产生鉴别关键,在<一个href=\"https://github.com/WindowsAzure/azure-sdk-for-node/blob/a19b6f1e91d134dd13f260b21c10aa7612f0e8fc/lib/services/blob/sharedkeylite.js\"相对=nofollow>这个的使用实现鉴别的NodeJS密钥生成的,我试图按照从<一个公认的答案href=\"http://stackoverflow.com/questions/21874694/how-to-set-azure-blob-storage-cors-properties-using-node\">this职位,但它并没有为我工作。
Based on REST API documentation to change CORS properties and to generate authentification key, on this implementation of authentification key generation using NodeJS, I tried to follow the accepted answer from this post, but it didn't work for me.
下面是我在setcrosproperties.js已经得到了:
Here is what I've got in setcrosproperties.js :
var crypto = require('crypto');
var request = require('request');
exports.setCors = function (MY_ACCOUNT_URL, MY_ACCOUNT_NAME, MY_ACCOUNT_HOST, accountKey) {
var MY_CORS_XML =
'<?xml version="1.0" encoding="utf-8"?>'+
'<StorageServiceProperties>'+
'<Cors>'+
'<CorsRule>'+
'<AllowedOrigins>*</AllowedOrigins>'+
'<AllowedMethods>GET,PUT</AllowedMethods>'+
'<MaxAgeInSeconds>500</MaxAgeInSeconds>'+
'<ExposedHeaders>x-ms-meta-data*,x-ms-meta-customheader</ExposedHeaders>'+
'<AllowedHeaders>x-ms-meta-target*,x-ms-meta-customheader</AllowedHeaders>'+
'</CorsRule>'+
'</Cors>'+
'<DefaultServiceVersion>2013-08-15</DefaultServiceVersion>'+
'</StorageServiceProperties>';
var url = MY_ACCOUNT_URL + '/?restype=service&comp=properties';
var canonicalizedResource = '/' + MY_ACCOUNT_NAME + '/?comp=properties';
var corsMD5 = crypto.createHash('md5' ).update(MY_CORS_XML).digest('base64');
var date = (new Date()).toUTCString();
var headers = {
'x-ms-version': '2013-08-15',
'x-ms-date': date,
'Host': MY_ACCOUNT_HOST
};
var canonicalizedHeaders = buildCanonicalizedHeaders( headers );
// THIS
var key = buildSharedKeyLite( 'PUT', corsMD5, 'text/plain; charset=UTF-8', canonicalizedHeaders, canonicalizedResource, accountKey);
// AND THIS, BOTH YIELD THE SAME SERVER RESPONSE
// var key = buildSharedKeyLite( 'PUT', "", "", canonicalizedHeaders, canonicalizedResource, accountKey);
headers['Authorization'] = 'SharedKeyLite ' + MY_ACCOUNT_NAME + ':' + key;
var options = {
url: url,
body: MY_CORS_XML,
headers: headers
};
console.log("url : " + url);
console.log("canonicalizedResource : " + canonicalizedResource);
console.log("canonicalizedHeaders : " + canonicalizedHeaders);
console.log("corsMD5 : " + corsMD5);
console.log("key : " + key);
console.log("options : " + JSON.stringify(options));
function onPropertiesSet(error, response, body) {
if (!error && response.statusCode == 202) {
console.log("CORS: OK");
}
else {
console.log("CORS: " + response.statusCode);
console.log("body : " + body);
}
}
request.put(options, onPropertiesSet); // require('request')
};
function buildCanonicalizedHeaders( headers ) {
var xmsHeaders = [];
var canHeaders = "";
for ( var name in headers ) {
if ( name.indexOf('x-ms-') == 0 ) {
xmsHeaders.push( name );
}
}
xmsHeaders.sort();
for ( var i = 0; i < xmsHeaders.length; i++ ) {
name = xmsHeaders[i];
canHeaders = canHeaders + name.toLowerCase().trim() + ':' + headers[name] + '\n';
}
return canHeaders;
}
function buildSharedKeyLite( verb, contentMD5, contentType, canonicalizedHeaders, canonicalizedResource, accountKey) {
var stringToSign = verb + "\n" +
contentMD5 + "\n" +
contentType + "\n" +
"" + "\n" + // date is to be empty because we use x-ms-date
canonicalizedHeaders +
canonicalizedResource;
// return crypto.createHmac('sha256', accountKey).update(encodeURIComponent(stringToSign)).digest('base64');
return crypto.createHmac('sha256', new Buffer(accountKey, 'base64')).update(stringToSign).digest('base64');
}
这是我如何调用该函数从我server.js文件:
And here is how I call this function from my server.js file :
var setcrosproperties = require('./setcrosproperties.js');
// setCors(MY_ACCOUNT_URL, MY_ACCOUNT_NAME, MY_ACCOUNT_HOST, accountKey)
setcrosproperties.setCors(
'https://'+process.env['AZURE_STORAGE_ACCOUNT']+'.blob.core.windows.net',
process.env['AZURE_STORAGE_ACCOUNT'],
process.env['AZURE_STORAGE_ACCOUNT']+'.blob.core.windows.net',
process.env['AZURE_STORAGE_ACCESS_KEY']);
我不明白的是什么打算与变量MY_ACCOUNT_UTL(我以为URL)和MY_ACCOUNT_HOST的差异,所以我用相同的值函数的两个参数。
I did not understand what was the difference intended with variables MY_ACCOUNT_UTL (I assumed URL) and MY_ACCOUNT_HOST, so I use the same value for both parameters of the function.
(我去掉了CORS参数,这似乎是不用的。)
(I removed the "cors" parameter, which seemed to be unused.)
下面是我在控制台中看到:
Here is what I get in the console :
网址:的https://NAME_OF_MY_STORAGE_ACCOUNT.blob.core.windows.net/?restype=service&comp=properties
canonicalizedResource:?/ NAME_OF_MY_STORAGE_ACCOUNT /补偿=性能
canonicalizedHeaders:X-MS-日期:孙老师,2014年3月9日12时33分41秒GMT
X-MS-版本:2013-08-15
corsMD5:+ IJ ...W¯¯==
关键:SNB ... JRY =
选项:{URL:的https://NAME_OF_MY_STORAGE_ACCOUNT.blob.core.windows.net/?restype=service&comp=properties\",\"body\":\"GET,PUT500x-ms-meta-data,x-ms-meta-customheaderx-ms-meta-target*,x-ms-meta-customheader2013-08-15\",\"headers\":{\"x-ms-version\":\"2013-08-15\",\"x-ms-date\":\"Sun, 2014年3月9日12时33分41秒格林尼治标准时间,主机:NAME_OF_MY_STORAGE_ACCOUNT.blob.core.windows.net,授权:SharedKeyLite NAME_OF_MY_STORAGE_ACCOUNT:SNB ... RY =}}
CORS:403
正文: AuthenticationFailed
服务器无法验证请求。确保授权头的值是正确形成,包括签名。
请求ID:1e6abfe3-e0e8-4b9c-922D-7cb34485eec9
时间:2014-03-09T12:33:在HTTP请求中发现'SNB ... JRY ='41.7262308ZThe MAC签名是不一样的任何计算签名。使用下面的字符串服务器签名:PUT
url : https://NAME_OF_MY_STORAGE_ACCOUNT.blob.core.windows.net/?restype=service&comp=properties canonicalizedResource : /NAME_OF_MY_STORAGE_ACCOUNT/?comp=properties canonicalizedHeaders : x-ms-date:Sun, 09 Mar 2014 12:33:41 GMT x-ms-version:2013-08-15 corsMD5 : +ij...w== key : sNB...JrY= options : {"url":"https://NAME_OF_MY_STORAGE_ACCOUNT.blob.core.windows.net/?restype=service&comp=properties","body":"GET,PUT500x-ms-meta-data,x-ms-meta-customheaderx-ms-meta-target*,x-ms-meta-customheader2013-08-15","headers":{"x-ms-version":"2013-08-15","x-ms-date":"Sun, 09 Mar 2014 12:33:41 GMT","Host":"NAME_OF_MY_STORAGE_ACCOUNT.blob.core.windows.net","Authorization":"SharedKeyLite NAME_OF_MY_STORAGE_ACCOUNT:sNB...rY="}} CORS: 403 body :
AuthenticationFailed
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:1e6abfe3-e0e8-4b9c-922d-7cb34485eec9 Time:2014-03-09T12:33:41.7262308ZThe MAC signature found in the HTTP request 'sNB...JrY=' is not the same as any computed signature. Server used following string to sign: 'PUT
X-MS-日期:孙老师,2014年3月9日12时33分41秒GMT
X-MS-版本:2013-08-15
/ NAME_OF_MY_STORAGE_ACCOUNT /?补偿=属性。
x-ms-date:Sun, 09 Mar 2014 12:33:41 GMT x-ms-version:2013-08-15 /NAME_OF_MY_STORAGE_ACCOUNT/?comp=properties'.
关于我做错了什么在这里的任何想法?感谢您的帮助。
Any idea about what I am doing wrong here? Thanks for your help
推荐答案
请添加内容类型
和的Content-MD5
在标题
阵列,并且应该做的伎俩。下面是修改code:
Please add Content-Type
and Content-MD5
in your headers
array and that should do the trick. Here's the modified code:
var crypto = require('crypto');
var request = require('request');
exports.setCors = function (MY_ACCOUNT_URL, MY_ACCOUNT_NAME, MY_ACCOUNT_HOST, accountKey) {
var MY_CORS_XML =
'<?xml version="1.0" encoding="utf-8"?>'+
'<StorageServiceProperties>'+
'<Cors>'+
'<CorsRule>'+
'<AllowedOrigins>*</AllowedOrigins>'+
'<AllowedMethods>GET,PUT</AllowedMethods>'+
'<MaxAgeInSeconds>500</MaxAgeInSeconds>'+
'<ExposedHeaders>x-ms-meta-data*,x-ms-meta-customheader</ExposedHeaders>'+
'<AllowedHeaders>x-ms-meta-target*,x-ms-meta-customheader</AllowedHeaders>'+
'</CorsRule>'+
'</Cors>'+
'<DefaultServiceVersion>2013-08-15</DefaultServiceVersion>'+
'</StorageServiceProperties>';
var url = MY_ACCOUNT_URL + '/?restype=service&comp=properties';
var canonicalizedResource = '/' + MY_ACCOUNT_NAME + '/?comp=properties';
var corsMD5 = crypto.createHash('md5' ).update(MY_CORS_XML).digest('base64');
var date = (new Date()).toUTCString();
var headers = {
'x-ms-version': '2013-08-15',
'x-ms-date': date,
'Host': MY_ACCOUNT_HOST,
'Content-Type': 'text/plain; charset=UTF-8',//Added this line
'Content-MD5': corsMD5,//Added this line
};
var canonicalizedHeaders = buildCanonicalizedHeaders( headers );
// THIS
var key = buildSharedKeyLite( 'PUT', corsMD5, 'text/plain; charset=UTF-8', canonicalizedHeaders, canonicalizedResource, accountKey);
// AND THIS, BOTH YIELD THE SAME SERVER RESPONSE
// var key = buildSharedKeyLite( 'PUT', "", "", canonicalizedHeaders, canonicalizedResource, accountKey);
headers['Authorization'] = 'SharedKeyLite ' + MY_ACCOUNT_NAME + ':' + key;
var options = {
url: url,
body: MY_CORS_XML,
headers: headers
};
console.log("url : " + url);
console.log("canonicalizedResource : " + canonicalizedResource);
console.log("canonicalizedHeaders : " + canonicalizedHeaders);
console.log("corsMD5 : " + corsMD5);
console.log("key : " + key);
console.log("options : " + JSON.stringify(options));
function onPropertiesSet(error, response, body) {
if (!error && response.statusCode == 202) {
console.log("CORS: OK");
}
else {
console.log("CORS: " + response.statusCode);
console.log("body : " + body);
}
}
request.put(options, onPropertiesSet); // require('request')
};
function buildCanonicalizedHeaders( headers ) {
var xmsHeaders = [];
var canHeaders = "";
for ( var name in headers ) {
if ( name.indexOf('x-ms-') == 0 ) {
xmsHeaders.push( name );
}
}
xmsHeaders.sort();
for ( var i = 0; i < xmsHeaders.length; i++ ) {
name = xmsHeaders[i];
canHeaders = canHeaders + name.toLowerCase().trim() + ':' + headers[name] + '\n';
}
return canHeaders;
}
function buildSharedKeyLite( verb, contentMD5, contentType, canonicalizedHeaders, canonicalizedResource, accountKey) {
var stringToSign = verb + "\n" +
contentMD5 + "\n" +
contentType + "\n" +
"" + "\n" + // date is to be empty because we use x-ms-date
canonicalizedHeaders +
canonicalizedResource;
// return crypto.createHmac('sha256', accountKey).update(encodeURIComponent(stringToSign)).digest('base64');
return crypto.createHmac('sha256', new Buffer(accountKey, 'base64')).update(stringToSign).digest('base64');
}
这篇关于Windows Azure的:使用设置的NodeJS一滴CORS性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!