介绍
Azure 存储帐户提供低成本、高可用性的数据服务。访问这些数据服务的主要方式是使用 REST API。对于您企业的自定义 REST API,您可能已经习惯使用 Postman 来测试、调试和监控它们。如果您可以留在 Postman 中与您的 Azure 存储帐户进行交互,那将会很方便,也许可以简化端到端测试或与您的团队成员共享请求。
在本指南中,您将了解如何使用 Postman 与存储帐户进行交互。您将设置身份验证,然后查询存储表和存储 blob。本指南基于上一个指南“设置 Postman 并自动添加 Bearer 令牌”。
Azure 存储帐户提供多种身份验证方式,包括存储 blob 和存储队列的托管标识、Azure AD 身份验证、共享密钥和共享访问签名 (SAS) 令牌。但是,最简单的解决方案是使用共享密钥。创建存储帐户时会为您提供两个密钥。它们有权在存储帐户上执行所有操作,因此务必小心安全地存储它们。
下面的代码片段展示了如何生成向存储表发出请求所需的授权值。
const storageAccount = pm.variables.get('azure_storage_account');
const accountKey = pm.variables.get('azure_storage_key');
const date = new Date();
const UTCstring = date.toUTCString();
const dataToEncode = UTCstring + "\n" + `/${storageAccount}${pm.request.url.getPath()}`;
const encodedData = unescape(encodeURIComponent(dataToEncode));
var hash = CryptoJS.HmacSHA256(encodedData, CryptoJS.enc.Base64.parse(accountKey));
var signature = hash.toString(CryptoJS.enc.Base64);
var auth = "SharedKeyLite " + storageAccount + ":" + signature;
pm.variables.set("header_authorization", auth);
pm.variables.set("header_date", UTCstring);
将此代码片段设置为预请求脚本后,您还需要设置标题以读取保存的变量。
GET https://{{azure_storage_account}}.table.core.windows.net/MyTable()?$filter=(PartitionKey eq 'PartitionA')
x-ms-date:{{header_date}}
Authorization:{{header_authorization}}
x-ms-version:2019-02-02
Accept:application/json;odata=nometadata
上面的标头详细信息演示了如何配置表存储查询的 URL 和标头。运行此请求时,它将返回与指定过滤器匹配的行的 JSON 列表。
您还可以使用共享密钥连接到 Blob 存储。但是,执行此操作的脚本稍微复杂一些。它如下所示,来源于Kamran Ayub 的 azure-storage-rest-postman GitHub 存储库。
// Set Date header value for authorization
// Should be UTC GMT string
pm.variables.set("header_date", new Date().toUTCString());
// Get hash of all header-name:value
const headers = pm.request.getHeaders({ ignoreCase: true, enabled: true });
// Construct Signature value for Authorization header
var signatureParts = [
pm.request.method.toUpperCase(),
headers["content-encoding"] || "",
headers["content-language"] || "",
headers["content-length"] || "",
// pm.request.body ? pm.request.body.toString().length || "" : "",
headers["content-md5"] || "",
headers["content-type"] || "",
headers["x-ms-date"] ? "" : (pm.variables.get("header_date") || ""),
headers["if-modified-since"] || "",
headers["if-match"] || "",
headers["if-none-match"] || "",
headers["if-unmodified-since"] || "",
headers["range"] || ""
];
// Construct CanonicalizedHeaders
const canonicalHeaderNames = [];
Object.keys(headers).forEach(key => {
if (key.startsWith("x-ms-")) {
canonicalHeaderNames.push(key);
}
});
// Sort headers lexographically by name
canonicalHeaderNames.sort();
const canonicalHeaderParts = [];
canonicalHeaderNames.forEach(key => {
let value = pm.request.getHeaders({ ignoreCase: true, enabled: true })[key];
// Populate variables
value = pm.variables.replaceIn(value);
// Replace whitespace in value but not if its within quotes
if (!value.startsWith("\"")) {
value = value.replace(/\s+/, " ");
}
canonicalHeaderParts.push(`${key}:${value}`);
});
// Add headers to signature
signatureParts.push.apply(signatureParts, canonicalHeaderParts);
// Construct CanonicalizedResource
const canonicalResourceParts = [
`/${pm.variables.get("azure_storage_account")}${pm.request.url.getPath()}`
];
const canonicalQueryNames = [];
pm.request.url.query.each(query => {
canonicalQueryNames.push(query.key.toLowerCase());
});
canonicalQueryNames.sort();
canonicalQueryNames.forEach(queryName => {
const value = pm.request.url.query.get(queryName);
// NOTE: This does not properly explode multiple same query params' values
// and turn them into comma-separated list
canonicalResourceParts.push(`${queryName}:${value}`);
});
// Add resource to signature
signatureParts.push.apply(signatureParts, canonicalResourceParts);
console.log("Signature Parts", signatureParts);
// Now, construct signature raw string
const signatureRaw = signatureParts.join("\n");
console.log("Signature String", JSON.stringify(signatureRaw));
// Hash it using HMAC-SHA256 and then encode using base64
const storageKey = pm.variables.get("azure_storage_key");
const signatureBytes = CryptoJS.HmacSHA256(signatureRaw, CryptoJS.enc.Base64.parse(storageKey));
const signatureEncoded = signatureBytes.toString(CryptoJS.enc.Base64);
console.log("Storage Account", pm.variables.get("azure_storage_account"));
console.log("Storage Key", storageKey);
// Finally, make it available for headers
pm.variables.set("header_authorization",
`SharedKey ${pm.variables.get("azure_storage_account")}:${signatureEncoded}`);
接下来需要设置请求头,类似于上面的表存储示例。
GET https://{{azure_storage_account}}.blob.core.windows.net/?restype=service&comp=properties
x-ms-date:{{header_date}}
Authorization:{{header_authorization}}
x-ms-version:2018-03-28
这将请求 blob 元数据属性。有关标头中可选和必需内容的更多详细信息,请阅读Microsoft 关于使用共享密钥授权的文档。
结论
如上所示,您可以使用 Postman 内部的共享密钥来查询 Azure 存储帐户资源(例如 Blob 和表)。这对于执行端到端 API 测试很有帮助。您可以在自定义 API 上运行 Postman 请求,并通过查询存储帐户来验证一切是否正常。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!