我正在尝试使用我的nodejs代码中的Rest API和SharedKeyLite更新Azure表存储,但收到身份验证错误 - “服务器无法验证请求。请确保正确形成Authorization标头的值,包括签名。”
请在下面找到我的nodejs代码 -
const Request = require('request');
const CryptoJS = require('crypto-js');
let apiVersion = '2018-03-28';
let contentType = 'application/json';
let dataServiceVersion = '3.0;NetFx';
let maxDataServiceVersion = '3.0;NetFx';
let storageAccountName = "mybotstorage";
let tableName = "myBotCounter";
let key = "**********************YO+MnTwBBbKKcPfsFQwg==";
var strTime = (new Date()).toUTCString();
let strToSign = strTime + '\n/' + storageAccountName + '/' + tableName + '(PartitionKey=\'mypartkey\',RowKey=\'myrowkey\')';
var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = "SharedKeyLite mybotstorage:" + hashInBase64;
var postData = {
"counter": "1050"
}
let content = Buffer.from(JSON.stringify(postData));
let contentLength = content.byteLength;
let headers = {};
headers['Authorization'] = auth;
headers['x-ms-date'] = strTime;
headers['x-ms-version'] = apiVersion;
headers['DataServiceVersion'] = dataServiceVersion;
headers['MaxDataServiceVersion'] = maxDataServiceVersion;
headers['Content-Type'] = contentType;
headers["Content-Length"] = contentLength;
headers["Accept-Charset"] = "UTF-8";
headers["Accept"] = "application/json";
let url = "https://mybotstorage.table.core.windows.net/" + tableName + "(PartitionKey='mypartky',RowKey='myrowkey')";
var options = {
headers: headers,
method: 'PUT',
body: content,
url: url
}
Request(options, function (err, res, body) {
if (err) {
console.error('error posting json: ', err)
throw err
}
var headers = res.headers;
var statusCode = res.statusCode;
console.log('headers: ', headers);
console.log('statusCode: ', statusCode);
console.log('body: ', body);
});
注意:使用'GET'检索数据并使用'POST'插入数据可以正常使用nodejs,但我无法使用nodejs中的'PUT'方法更新数据。
我还使用C#代码测试了'PUT'方法,它工作正常,但nodejs代码给出了身份验证错误。
问题是由于url的编码,C#和NodeJS以不同的方式处理。我发布了工作代码示例以供参考。
const Request = require('request');
const CryptoJS = require('crypto-js');
let apiVersion = '2013-08-15';
let contentType = 'application/json';
let storageAccountName = "mybotstorage";
let tableName = "myBotCounter";
let key = "*******************************YO+MnTwBBbKKcPfsFQwg==";
let strTime = (new Date()).toUTCString();
let strToSign = strTime + '\n/' + storageAccountName + '/' + tableName + '(PartitionKey=%27mypartitionkey%27,RowKey=%27myrowkey%27)';
let secret = CryptoJS.enc.Base64.parse(key);
let hash = CryptoJS.HmacSHA256(strToSign, secret);
let hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
let auth = "SharedKeyLite mybotstorage:" + hashInBase64;
console.log(strToSign);
console.log(auth);
let postData = {
"counter": "1088"
}
let headers = {};
headers['Content-Type'] = contentType;
headers['Authorization'] = auth;
headers['x-ms-date'] = strTime;
headers['x-ms-version'] = apiVersion;
let url = "https://mybotstorage.table.core.windows.net/" + tableName + "(PartitionKey=%27mypartitionkey%27,RowKey=%27myrowkey%27)";
console.log('url------', url);
var options = {
headers: headers,
method: 'PUT',
body: JSON.stringify(postData),
url: url
}
Request(options, function (err, res, body) {
if (err) {
console.error('error posting json: ', err)
throw err
}
var headers = res.headers;
var statusCode = res.statusCode;
console.log('headers: ', headers);
console.log('statusCode: ', statusCode);
console.log('body: ', body);
});