我正在尝试在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请求“ [signature]”中找到的MAC签名不是 与任何计算出的签名相同。服务器使用以下字符串进行签名: 'PUT \ n \ n \ n1762213 \ n \ nimage / png \ n \ n \ n \ n \ n \ n \ nx-ms-date:2020年9月24日,星期四 12:24:05 GMT \ nx-ms-version:2019-12-12 \ n / [帐户名称] / [容器 名称] / [文件夹名称] /image.png'。
很显然,我已经删除了实际的签名,因为我已经将其用于服务器端,但是它看起来像这样:hGhg765 + NIGjhgluhuUYG686dnH90HKYFytf6 =(我做了这个,但看起来好像是正确的格式)。>
我也尝试返回解析的查询字符串并在PUT请求中使用,但是随后出现错误,指出缺少所需的标头,并且我无法确定应该是哪个标头。例如,无需Authorization
。
答案 0 :(得分:0)
方法generateDataLakeSASQueryParameters
用于创建service sas token。之后,我们可以使用sas令牌作为查询参数调用Azure Datalake Rest API
例如
generateDataLakeSASQueryParameters
创建一个sas令牌。当我们调用方法generateDataLakeSASQueryParameters
时,我们应该定义一个DataLakeSASSignatureValues
类:https://docs.microsoft.com/en-us/javascript/api/@azure/storage-file-datalake/datalakesassignaturevalues?view=azure-node-latest const {
StorageSharedKeyCredential,
generateDataLakeSASQueryParameters,
DataLakeSASPermissions,
} = require("@azure/storage-file-datalake");
const accountName = "testadls05";
const accountKey ="";
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 fileSas = generateDataLakeSASQueryParameters(
{
fileSystemName: "test",
pathName: "test.jpg",
permissions: DataLakeSASPermissions.parse("racwd"),
startsOn: startsOn,
expiresOn: expiresOn,
},
new StorageSharedKeyCredential(accountName, accountKey)
).toString();
console.log(fileSas);
PUT http:// https://{accountName}.{dnsSuffix}/{filesystem}/{path}
?{sas token you create in step1}
Headers:
Content-Type:image/jpeg
Content-Length:0