如何通过 Javascript (node.js) 生成 Azure SAS 令牌
How to generate an Azure SAS token via Javascript (node.js)
我正在尝试生成一个有效的 SAS 令牌(共享访问签名)以连接到 Azure IoT 中心,但我在使用令牌时一直收到错误 Connection refused: Not authorized
。
我知道我的连接方式是有效的,因为当使用由 Microsoft Device Explorer (https://github.com/Azure/azure-iot-sdk-csharp/tree/master/tools/DeviceExplorer) 生成的 SAS 令牌时,它按预期工作。
为了编写 Javascript 代码,我从这个文档开始 https://docs.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1 与一些工作实现进行比较:
- 在 Python 中:https://github.com/Azure/azure-sdk-for-python/blob/master/azure-servicebus/azure/servicebus/servicebusservice.py
- 在 Go/Golang 中:https://github.com/openenergi/go-event-hub/blob/master/msauth/sasl.go
我在下面的Javascript实现中做错了什么?我认为这可能与SHA256签名结合URL转义字符串有关但我不确定如何 test/verify 这个。
const crypto = require('crypto');
// on the Azure Portal:
// sharedAccessKeyName is the "policy" field
// sharedAccessKeyValue is the "primary key"
const sign = (iotHubName, expirtyDeltaInSecondsFromNow, sharedAccessKeyName, sharedAccessKeyValue) => {
// URL encode the IoT Hub host
const encodedSasUrl = encodeURI(`${iotHubName}.azure-devices.net`.toLowerCase());
// calculate the expiry end datetime as an epoch
const expiry = parseInt(Date.now() / 1000 + expirtyDeltaInSecondsFromNow);
// combine the previous two pieces of information
const stringToSign = `${encodedSasUrl}\n${expiry}`;
// sign the string using the primary key (sharedAccessKeyValue) and SHA256
const hmac = crypto.createHmac('sha256', sharedAccessKeyValue);
hmac.update(stringToSign);
const hash = hmac.digest('hex');
// encode the signed hash to base64 (making sure it's URL escaped)
const encodedSignature = hash.toString('base64');
// put all together into the SAS token
const sasToken = `SharedAccessSignature sig=${encodedSignature}&se=${expiry}&skn=${sharedAccessKeyName}&sr=${encodedSasUrl}`;
console.log("sasToken:", sasToken);
return sasToken;
}
Here 是通过 node.js.
生成 SAS 令牌的示例
var generateSasToken = function(resourceUri, signingKey, policyName, expiresInMins) {
resourceUri = encodeURIComponent(resourceUri);
// Set expiration in seconds
var expires = (Date.now() / 1000) + expiresInMins * 60;
expires = Math.ceil(expires);
var toSign = resourceUri + '\n' + expires;
// Use crypto
var hmac = crypto.createHmac('sha256', new Buffer(signingKey, 'base64'));
hmac.update(toSign);
var base64UriEncoded = encodeURIComponent(hmac.digest('base64'));
// Construct autorization string
var token = "SharedAccessSignature sr=" + resourceUri + "&sig="
+ base64UriEncoded + "&se=" + expires;
if (policyName) token += "&skn="+policyName;
return token;
};
What am I doing wrong in the following Javascript implementation?
我不是 javascript(node.js) 方面的专家。也许你可以通过比较上面的代码和你的代码来弄清楚。
我正在尝试生成一个有效的 SAS 令牌(共享访问签名)以连接到 Azure IoT 中心,但我在使用令牌时一直收到错误 Connection refused: Not authorized
。
我知道我的连接方式是有效的,因为当使用由 Microsoft Device Explorer (https://github.com/Azure/azure-iot-sdk-csharp/tree/master/tools/DeviceExplorer) 生成的 SAS 令牌时,它按预期工作。
为了编写 Javascript 代码,我从这个文档开始 https://docs.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1 与一些工作实现进行比较:
- 在 Python 中:https://github.com/Azure/azure-sdk-for-python/blob/master/azure-servicebus/azure/servicebus/servicebusservice.py
- 在 Go/Golang 中:https://github.com/openenergi/go-event-hub/blob/master/msauth/sasl.go
我在下面的Javascript实现中做错了什么?我认为这可能与SHA256签名结合URL转义字符串有关但我不确定如何 test/verify 这个。
const crypto = require('crypto');
// on the Azure Portal:
// sharedAccessKeyName is the "policy" field
// sharedAccessKeyValue is the "primary key"
const sign = (iotHubName, expirtyDeltaInSecondsFromNow, sharedAccessKeyName, sharedAccessKeyValue) => {
// URL encode the IoT Hub host
const encodedSasUrl = encodeURI(`${iotHubName}.azure-devices.net`.toLowerCase());
// calculate the expiry end datetime as an epoch
const expiry = parseInt(Date.now() / 1000 + expirtyDeltaInSecondsFromNow);
// combine the previous two pieces of information
const stringToSign = `${encodedSasUrl}\n${expiry}`;
// sign the string using the primary key (sharedAccessKeyValue) and SHA256
const hmac = crypto.createHmac('sha256', sharedAccessKeyValue);
hmac.update(stringToSign);
const hash = hmac.digest('hex');
// encode the signed hash to base64 (making sure it's URL escaped)
const encodedSignature = hash.toString('base64');
// put all together into the SAS token
const sasToken = `SharedAccessSignature sig=${encodedSignature}&se=${expiry}&skn=${sharedAccessKeyName}&sr=${encodedSasUrl}`;
console.log("sasToken:", sasToken);
return sasToken;
}
Here 是通过 node.js.
生成 SAS 令牌的示例var generateSasToken = function(resourceUri, signingKey, policyName, expiresInMins) {
resourceUri = encodeURIComponent(resourceUri);
// Set expiration in seconds
var expires = (Date.now() / 1000) + expiresInMins * 60;
expires = Math.ceil(expires);
var toSign = resourceUri + '\n' + expires;
// Use crypto
var hmac = crypto.createHmac('sha256', new Buffer(signingKey, 'base64'));
hmac.update(toSign);
var base64UriEncoded = encodeURIComponent(hmac.digest('base64'));
// Construct autorization string
var token = "SharedAccessSignature sr=" + resourceUri + "&sig="
+ base64UriEncoded + "&se=" + expires;
if (policyName) token += "&skn="+policyName;
return token;
};
What am I doing wrong in the following Javascript implementation?
我不是 javascript(node.js) 方面的专家。也许你可以通过比较上面的代码和你的代码来弄清楚。