理想情况下,我想访问存储中的所有容器和 blob。 帐户 SAS token 是在我的代码中在服务器端生成的。客户端将调用我在 Node.js 中创建的 API 来接收它。我发现您可以使用 Azure Shell 手动创建 SAS token ,但我更喜欢在服务器端生成它,因为将实现身份验证。
遵循 account SAS generation documentation ,它指出要签名的字符串应该像这样构造。
StringToSign = accountname + "\n" +
signedpermissions + "\n" +
signedservice + "\n" +
signedresourcetype + "\n" +
signedstart + "\n" + // optional
signedexpiry + "\n" +
signedIP + "\n" + // optional
signedProtocol + "\n" + // optional
signedversion + "\n"
文档中的示例 token (为了更好的可见性分成多行):
sv=2019-02-02&ss=bf&srt=s&st=2019-08-01T22%3A18%3A26Z
&se=2019-08-10T02%3A23%3A26Z&sr=b&sp=rw
&sip=168.1.5.60-168.1.5.70&spr=https
&sig=F%6GRVAZ5Cdj2Pw4tgU7IlSTkWgn7bUkkAg8P6HESXwmf%4B
从 Azure Shell 生成的 token :
se=2019-11-15&sp=rwdlac&sv=2018-03-28&ss=b&srt=sco&sig=<hidden signature>
奇怪的是,在示例 token 中,首先提供了 signedversion (sv),而不是 Azure Shell 中的 token 中的 signedexpiry (se)。
下面是用于生成 token 的代码。我尝试遵循与 Azure Shell 中的 token 相同的顺序:
app.get('/sas-token', (req, res, next) => {
// const start = new Date(new Date().getTime() - (15 * 60 * 1000));
const end = new Date(new Date().getTime() + (30 * 60 * 1000));
const signedpermissions = 'rwdlac';
const signedversion = '2018-03-28';
const signedservice = 'b';
const signedresourcetype = 'sco';
// const signedstart = truncateIsoDate(start);
const signedexpiry = truncateIsoDate(end);
// const signedIP = '';
const signedProtocol = 'https';
const StringToSign = STORAGE_ACCOUNT_NAME + "\n" +
signedpermissions + "\n" +
signedservice + "\n" +
signedresourcetype + "\n" +
// signedstart + "\n" +
signedexpiry + "\n" +
// signedIP + "\n" +
signedProtocol + "\n" +
signedversion + "\n"
const key = new Buffer(ACCOUNT_ACCESS_KEY, 'base64');
let sig = crypto.createHmac('sha256', key).update(StringToSign, 'utf8').digest('base64');
let sas =
`se=${signedexpiry}
&sp=${(signedpermissions)}
&sv=${(signedversion)}
&ss=${(signedservice)}
&srt=${(signedresourcetype)}
&sig=${encodeURIComponent(sig)}`;
res.json({
storageUri: STORAGE_ACCOUNT_NAME,
storageAccessToken: sas
});
});
当我的客户端最终使用生成的 SAS token 发出请求时,我收到一条错误:
403 (Server failed to authenticate the request.
Make sure the value of Authorization header is formed correctly including the signature.)
是否可以为 Node.js 中的 Blob 存储生成帐户 SAS token ?
最佳答案
根据我的研究,我们可以使用Azure存储SDK azure-storage
。更多详情请引用https://github.com/Azure/azure-storage-node/blob/0557d02cd2116046db1a2d7fc61a74aa28c8b557/test/accountsas-tests.js .
var storage = require("azure-storage")
var startDate = new Date();
var expiryDate = new Date();
startDate.setTime(startDate.getTime() - 5*60*1000);
expiryDate.setTime(expiryDate.getTime() + 24*60*60*1000);
var AccountSasConstants = storage.Constants.AccountSasConstants;
var sharedAccessPolicy = {
AccessPolicy: {
Services: AccountSasConstants.Services.BLOB ,
ResourceTypes: AccountSasConstants.Resources.SERVICE +
AccountSasConstants.Resources.CONTAINER +
AccountSasConstants.Resources.OBJECT,
Permissions: AccountSasConstants.Permissions.READ +
AccountSasConstants.Permissions.ADD +
AccountSasConstants.Permissions.CREATE +
AccountSasConstants.Permissions.WRITE +
AccountSasConstants.Permissions.DELETE +
AccountSasConstants.Permissions.LIST,
Protocols: AccountSasConstants.Protocols.HTTPSORHTTP,
Start: startDate,
Expiry: expiryDate
}
};
const accountname ="blobstorage0516";
const key = "";
var sas =storage.generateAccountSharedAccessSignature(accountname,key,sharedAccessPolicy);
console.log(sas);
此外,如果您不想使用 SDK 生成 SAS token ,请注意,如果我们不使用 StringToSign
中的一个属性,我们就不能省略 \n
> 当我们创建 sas token 时,应该使用我们在 StringToSign
中提供的属性。
例如
const accountname ="blobstorage0516";
const key = "";
const start = new Date(new Date().getTime() - (15 * 60 * 1000));
const end = new Date(new Date().getTime() + (30 * 60 * 1000));
const signedpermissions = 'rwdlac';
const signedservice = 'b';
const signedresourcetype = 'sco';
const signedexpiry = end.toISOString().substring(0, end.toISOString().lastIndexOf('.')) + 'Z';
const signedProtocol = 'https';
const signedversion = '2018-03-28';
const StringToSign =
accountname + '\n' +
signedpermissions + '\n' +
signedservice + '\n' +
signedresourcetype + '\n' +
'\n' +
signedexpiry + '\n' +
'\n' +
signedProtocol + '\n' +
signedversion + '\n';
let sig = crypto.createHmac('sha256', Buffer.from(key, 'base64')).update(StringToSign, 'utf8').digest('base64');
let sasToken =
`sv=${(signedversion)}&ss=${(signedservice)}&srt=${(signedresourcetype)}&sp=${(signedpermissions)}&se=${encodeURIComponent(signedexpiry)}&spr=${(signedProtocol)}&sig=${encodeURIComponent(sig)}`;
console.log(sasToken)
var storageBlobEndpoint = "https://"+ accountname +".blob.core.windows.net"
var container="blobcontainer";
var blobName="CP4.png";
var requestURL = storageBlobEndpoint + "/" + container + "/" + blobName +"?"+sasToken
console.log(requestURL)
<小时/>
更新
根据我的测试,我们可以使用上面代码创建的 sas token 在 Azure blob 存储上执行 smoe 操作。例如
1。列出容器
Get https://<your account>.blob.core.windows.net/?comp=list+ "&"+"<your sas token>"
2。获取容器属性
Get https://<your account>.blob.core.windows.net/<your container>?restype=container&comp=list +"&" +"<your sas token>"
另外,如何使用新的sdk @azure/storage-blob
创建SAS token,请引用以下代码
const accountname ="blobstorage0516";
const key = "";
const signedpermissions = 'rwdlac';
const signedservice = 'b';
const signedresourcetype = 'sco';
const signedProtocol = 'https';
const signedversion = '2018-03-28';
const cerds = new storage.StorageSharedKeyCredential(accountname,key);
var startDate = new Date();
var expiryDate = new Date();
startDate.setTime(startDate.getTime() - 5*60*1000);
expiryDate.setTime(expiryDate.getTime() + 24*60*60*1000);
expiryDate.setTime(expiryDate.getTime() + 24*60*60*1000);
var result = storage.generateAccountSASQueryParameters({
expiresOn : expiryDate,
permissions: storage.AccountSASPermissions.parse(signedpermissions),
protocol: storage.SASProtocol.Https,
resourceTypes: storage.AccountSASResourceTypes.parse(signedresourcetype).toString(),
services: storage.AccountSASServices.parse(signedservice).toString(),
startsOn: startDate,
version:signedversion
},cerds).toString();
console.log(result);
关于javascript - 如何为Azure存储生成帐户SAS token ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58827196/