使用特定于 Blob 的 SAS 令牌连接和更新 Azure Blob
Connect and update Azure Blob with Blob-specific SAS Token
我想做什么:我有一个客户端(浏览器,而不是 node.js)JS 应用程序,它使用 @azure/storage-blob
包将文件上传到 Blob 存储。为此,它从特定 Blob 的 Azure 函数中获取 SAS 令牌。 Blob 由 Function 在每次请求时创建,并且 SAS Token 返回给客户端。 Blob 和 SAS 生成工作正常,当在浏览器中打开带有 SAS 的 Blob Url 时,我可以下载它。
现在,当我尝试将 BLOB SAS(不是存储帐户 SAS 或连接字符串)连接到存储帐户时,不起作用。下面的代码在整个存储帐户中与 SAS 一起使用时有效,但我不想授予那么多权限。我不明白为什么可以为特定的 Blob 创建 SAS 令牌,如果无法通过 Blob 服务客户端连接到它。
可以为整个存储帐户创建只读 SAS 令牌以建立连接并 运行。但是 Blob SAS 之后会去哪里,以便可以访问 Blob?
我似乎错过了一些基本的东西,那么如何实现呢?
const url = `https://${storageName}.blob.core.windows.net/${sasToken}`; // sas for blob from the azure function
// const url = `https://${storageName}.blob.core.windows.net${containerSas}`; // sas from container
// const url = `https://${storageName}.blob.core.windows.net/${containerName}/${fileName}${sasToken}`; // does not work either
const blobService = new BlobServiceClient(url);
await this.setCors(blobService);
// get Container
const containerClient: ContainerClient = blobService.getContainerClient(containerName);
// get client
const blobClient = containerClient.getBlockBlobClient(fileName);
const exists = await blobClient.exists();
console.log('Exists', exists);
// set mimetype as determined from browser with file upload control
const options: BlockBlobParallelUploadOptions = { blobHTTPHeaders: { blobContentType: file.type } };
// upload file
await blobClient.uploadBrowserData(file, options);
编辑:
Blob 的 SAS 令牌:
?sv=2018-03-28&sr=b&sig=somesecret&se=2021-07-04T15%3A14%3A28Z&sp=racwl
CORS 方法,虽然我可以确认它在我使用全局存储帐户 SAS 时有效:
private async setCors(blobService: BlobServiceClient): Promise<void> {
var props = await blobService.getProperties();
props.
cors =
[{
allowedOrigins: '*',
allowedMethods: '*',
allowedHeaders: '*',
exposedHeaders: '*',
maxAgeInSeconds: 3600
}]
;
}
错误:
使用 Blob SAS 时,在 setCors/getProperties 方法中:403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.)
在 setCors/getProperties 方法中使用以下服务 url 时:https://${storageName}.blob.core.windows.net/${containerName}/${fileName}${sasToken}
=> RestError: The resource doesn't support specified Http Verb.
当使用只有 READ 权限的存储帐户 SAS 时,在访问 blob (blob.exists()) 时:403 (This request is not authorized to perform this operation using this resource type.)
(有道理,但我想使用 Blob-specific SAS)
您 运行 陷入此错误的原因是因为您尝试使用为 blob 创建的 SAS 令牌(它是 Service SAS
). CORS operation is a service level operation and for that you need to use a SAS token obtained at the account level. In other words, you will need to use an Account SAS
。为创建的任何 SAS 令牌设置 CORS blob 容器或 blob 是 Service SAS
标记。
话虽如此,您确实不需要在每个请求中的存储帐户上设置 CORS 属性。这是您可以在创建帐户时执行的操作。
从代码中删除对 setCors
方法的调用后,它应该可以正常工作。
考虑到您只使用 Blob SAS,您可以通过直接使用 SAS URL 创建 BlockBlobClient
的实例来大大简化代码。例如,您的代码可以像这样简单:
const url = `https://${storageName}.blob.core.windows.net/${containerName}/${fileName}${sasToken}`;
const blobClient = new BlockBlobClient(url);
//...do operations on blob using this blob client
我想做什么:我有一个客户端(浏览器,而不是 node.js)JS 应用程序,它使用 @azure/storage-blob
包将文件上传到 Blob 存储。为此,它从特定 Blob 的 Azure 函数中获取 SAS 令牌。 Blob 由 Function 在每次请求时创建,并且 SAS Token 返回给客户端。 Blob 和 SAS 生成工作正常,当在浏览器中打开带有 SAS 的 Blob Url 时,我可以下载它。
现在,当我尝试将 BLOB SAS(不是存储帐户 SAS 或连接字符串)连接到存储帐户时,不起作用。下面的代码在整个存储帐户中与 SAS 一起使用时有效,但我不想授予那么多权限。我不明白为什么可以为特定的 Blob 创建 SAS 令牌,如果无法通过 Blob 服务客户端连接到它。
可以为整个存储帐户创建只读 SAS 令牌以建立连接并 运行。但是 Blob SAS 之后会去哪里,以便可以访问 Blob?
我似乎错过了一些基本的东西,那么如何实现呢?
const url = `https://${storageName}.blob.core.windows.net/${sasToken}`; // sas for blob from the azure function
// const url = `https://${storageName}.blob.core.windows.net${containerSas}`; // sas from container
// const url = `https://${storageName}.blob.core.windows.net/${containerName}/${fileName}${sasToken}`; // does not work either
const blobService = new BlobServiceClient(url);
await this.setCors(blobService);
// get Container
const containerClient: ContainerClient = blobService.getContainerClient(containerName);
// get client
const blobClient = containerClient.getBlockBlobClient(fileName);
const exists = await blobClient.exists();
console.log('Exists', exists);
// set mimetype as determined from browser with file upload control
const options: BlockBlobParallelUploadOptions = { blobHTTPHeaders: { blobContentType: file.type } };
// upload file
await blobClient.uploadBrowserData(file, options);
编辑:
Blob 的 SAS 令牌:
?sv=2018-03-28&sr=b&sig=somesecret&se=2021-07-04T15%3A14%3A28Z&sp=racwl
CORS 方法,虽然我可以确认它在我使用全局存储帐户 SAS 时有效:
private async setCors(blobService: BlobServiceClient): Promise<void> {
var props = await blobService.getProperties();
props.
cors =
[{
allowedOrigins: '*',
allowedMethods: '*',
allowedHeaders: '*',
exposedHeaders: '*',
maxAgeInSeconds: 3600
}]
;
}
错误:
使用 Blob SAS 时,在 setCors/getProperties 方法中:403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.)
在 setCors/getProperties 方法中使用以下服务 url 时:https://${storageName}.blob.core.windows.net/${containerName}/${fileName}${sasToken}
=> RestError: The resource doesn't support specified Http Verb.
当使用只有 READ 权限的存储帐户 SAS 时,在访问 blob (blob.exists()) 时:403 (This request is not authorized to perform this operation using this resource type.)
(有道理,但我想使用 Blob-specific SAS)
您 运行 陷入此错误的原因是因为您尝试使用为 blob 创建的 SAS 令牌(它是 Service SAS
). CORS operation is a service level operation and for that you need to use a SAS token obtained at the account level. In other words, you will need to use an Account SAS
。为创建的任何 SAS 令牌设置 CORS blob 容器或 blob 是 Service SAS
标记。
话虽如此,您确实不需要在每个请求中的存储帐户上设置 CORS 属性。这是您可以在创建帐户时执行的操作。
从代码中删除对 setCors
方法的调用后,它应该可以正常工作。
考虑到您只使用 Blob SAS,您可以通过直接使用 SAS URL 创建 BlockBlobClient
的实例来大大简化代码。例如,您的代码可以像这样简单:
const url = `https://${storageName}.blob.core.windows.net/${containerName}/${fileName}${sasToken}`;
const blobClient = new BlockBlobClient(url);
//...do operations on blob using this blob client