【发布时间】:2020-09-25 16:17:52
【问题描述】:
我正在尝试在我的 Node 应用程序中创建共享访问签名客户端。原因是我不想通过我的应用程序流式传输文件。我希望用户能够直接将文件上传到我的 Azure Data Lake Gen2 Blob 存储容器。
我查看了我能找到的所有示例,但它们都是服务器端的。所以我尝试生成generateDataLakeSASQueryParameters 并在PUT 请求中使用它们。该过程看起来有效,我将其返回给客户。
服务器端:
async getFileUploadUrl(path) {
const now = new Date().toUTCString();
const startsOn = new Date(now);
startsOn.setMinutes(startsOn.getMinutes() - 10); // Skip clock skew with server
const expiresOn = new Date(now);
expiresOn.setHours(expiresOn.getHours() + 1); // Expires in one hour
const sharedKeyCredential = new StorageSharedKeyCredential(this.storageAccountName, this.accountKey);
const sas = generateDataLakeSASQueryParameters({
fileSystemName: this.fileSystemClient.name,
ipRange: { start: "0.0.0.0", end: "255.255.255.255" },
expiresOn,
protocol: SASProtocol.HttpsAndHttp,
permissions: DataLakeSASPermissions.parse("c").toString(), // Read (r), Write (w), Delete (d), List (l), Add (a), Create (c), Update (u), Process (p)
resourceTypes: AccountSASResourceTypes.parse("o").toString(), // Service (s), Container (c), Object (o)
services: AccountSASServices.parse("b").toString(), // Blob (b), Table (t), Queue (q), File (f)
startsOn,
version: "2019-12-12"
},
sharedKeyCredential);
const encodedURI = encodeURI(path);
const filePath = `${this.fileSystemClient.url}/${encodedURI}`;
return {
url: filePath,
signature: sas.signature,
};
}
客户端:
const { url, signature } = serverResponse;
const file = [file takes from an input tag];
const request = new XMLHttpRequest();
request.open('PUT', url, true);
request.setRequestHeader("x-ms-date", new Date().toUTCString());
request.setRequestHeader("x-ms-version", '2019-12-12');
request.setRequestHeader("x-ms-blob-type", 'BlockBlob');
request.setRequestHeader("Authorization", `SharedKey [storageaccount]:${signature}`);
request.send(file);
我不断返回的是带有以下错误的 403:
在 HTTP 请求“[签名]”中找到的 MAC 签名不是 与任何计算的签名相同。服务器使用以下字符串进行签名: 'PUT\n\n\n1762213\n\nimage/png\n\n\n\n\n\n\nx-ms-date:Thu, 2020 年 9 月 24 日 格林威治标准时间 12:24:05\nx-ms-version:2019-12-12\n/[账户名]/[容器 名称]/[文件夹名称]/image.png'。
显然我已经删除了实际签名,因为我已经将它用于服务器端,但它看起来像这样:hGhg765+NIGjhgluhuUYG686dnH90HKYFytf6=(我编造了这个,但它看起来好像格式正确)。
我还尝试返回解析后的查询字符串并在 PUT 请求中使用,但随后我收到错误消息,指出缺少必需的标头,我无法确定应该是哪个标头。例如,不需要Authorization。
【问题讨论】:
标签: javascript node.js azure-data-lake-gen2