简体   繁体   English

使用 Node.js 服务器为 Next.js 授权 Azure 存储服务 REST API - 从 URL 复制 Blob

[英]Authorization of Azure Storage service REST API for Next.js with Node.js server - Copy Blob From URL

Reference1: https://docs.microsoft.com/en-us/rest/api/storageservices/copy-blob-from-url参考 1: https : //docs.microsoft.com/en-us/rest/api/storageservices/copy-blob-from-url

Reference2: Authorization of Azure Storage service REST API参考 2: Azure 存储服务 REST API 的授权

I implemented listing of containers according to the above reference2 as a backend server in Next.js (/pages/api/).我在 Next.js (/pages/api/) 中作为后端服务器根据上述参考实现了容器列表。 I got the implementation in Reference2 to work with response status===OK.我得到了 Reference2 中的实现来处理响应状态===OK。 My goal is to copy a blob with tier===cool and paste it into a different container with tier===archive so I don't have to change the archived blob's access tier when downloading it.我的目标是复制一个带有 tier===cool 的 blob 并将其粘贴到带有 tier===archive 的不同容器中,这样我在下载它时就不必更改存档 blob 的访问层。

I follow exactly reference2 with the following changes:我完全按照reference2进行了以下更改:

  1. set strToSign to (least sure about this part):将 strToSign 设置为(最不肯定这部分):

const strToSign= PUT\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nx-ms-date:${strTime}\\nx-ms-version:2020-10-02\\n/${account}/\\n${containerName}/${blobName} const strToSign= PUT\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nx-ms-date:${strTime}\\nx-ms-version:2020-10-02\\n/${account}/\\n${containerName}/${blobName}

  1. set header (following reference1) to:将标题(以下参考文献1)设置为:

     const putConfig = { method: 'PUT', headers: { 'Authorization': auth, 'x-ms-date': strTime, 'x-ms-version': "2020-10-02", 'x-ms-copy-source': blobUrl, 'x-ms-requires-sync':'true' }

    } }

where (as in reference1),其中(如参考文献1),

   const blobUrl = `https://${account}.blob.core.windows.net/${containerName}/${blobName}`
  1. The fetch is set up like this:提取设置如下:

    fetch( https://${account}.blob.core.windows.net/${containerName}/${blobName} , putConfig) .then( results => console.log(results), res.end()) fetch( https://${account}.blob.core.windows.net/${containerName}/${blobName} , putConfig) .then( results => console.log(results), res.end())

  2. This is the console.log(results) output I get:这是我得到的 console.log(results) 输出:

    Response { size: 0, timeout: 0, [Symbol(Body internals)]: { body: PassThrough { _readableState: [ReadableState], _events: [Object: null prototype], _eventsCount: 2, _maxListeners: undefined, _writableState: [WritableState], allowHalfOpen: true, [Symbol(kCapture)]: false, [Symbol(kCallback)]: null }, disturbed: false, error: null }, [Symbol(Response internals)]: { url: 'https://.blob.core.windows.net//', status: 403, statusText: 'Server failed to authenticate the request.响应 { size: 0, timeout: 0, [Symbol(Body internals)]: { body: PassThrough { _readableState: [ReadableState], _events: [Object: null prototype], _eventsCount: 2, _maxListeners: undefined, _writableState: [WritableState ], allowHalfOpen: true, [Symbol(kCapture)]: false, [Symbol(kCallback)]: null }, 不安: false, error: null }, [Symbol(Response internals)]: { url: 'https:// .blob.core.windows.net//', status: 403, statusText: '服务器验证请求失败。 Make sure the value of Authorization header is formed correctly including the signature.', headers: Headers { [Symbol(map)]: [Object: null prototype] }, counter: 0 } }确保 Authorization header 的值包含签名正确形成。', headers: Headers { [Symbol(map)]: [Object: null prototype] }, counter: 0 } }

Not sure what the error is - can it be related to setting access on the specific blob (resource) on azure portal?不确定错误是什么 - 是否与在 azure 门户上设置对特定 blob(资源)的访问权限有关? How do you fix this issue?你如何解决这个问题?

PS聚苯乙烯

Reference3: Authentication Failed in REST api call to PUT Blob in Azure Storage [REST][Azure Blob]参考 3: 在 Azure 存储 [REST][Azure Blob] 中对 PUT Blob 的 REST api 调用中的身份验证失败

I also tried to use the following:我还尝试使用以下内容:

const strToSign = `PUT\n\n\n\n\n\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:${strTime}\nx-ms-version:2020-10-02\n/${account}/\n${containerName}/\n${blobName}`;

The error remains the same.错误保持不变。

As Suggested By Gaurav Matri根据Gaurav Matri 的建议

blob is in the archive access tier , it's considered to be offline and can't be read or modified. blob 位于存档访问层中,它被认为是脱机的,无法读取或修改。

In order to read or modify data in an archived blob, you must first rehydrate the blob to an online tier, either the hot or cool tier .为了读取或修改存档 blob 中的数据,您必须首先将 blob 重新水合到在线层,即热层或冷层

There are two options for rehydrating a blob that is stored in the archive tier:有两个选项可用于重新组合存储在存档层中的 blob:

  1. Copy an archived blob to an online tier将存档的 blob 复制到在线层

You can rehydrate an archived blob by copying it to a new blob in the hot or cool tier with the Copy Blob or Copy Blob from URL operation.您可以通过使用“复制 Blob”或“从 URL 复制 Blob”将存档的 Blob 复制到热层或冷层中的新 Blob 来重新水合存档 Blob。 Microsoft recommends this option for most scenarios. Microsoft 建议在大多数情况下使用此选项。

  1. Change a blob's access tier to an online tier将 Blob 的访问层更改为在线层

You can rehydrate an archived blob to hot or cool by changing its tier using the Set Blob Tier operation.您可以通过使用Set Blob Tier操作更改其层, 存档的 Blob 重新水合为热或冷。

For more details refer this document有关更多详细信息,请参阅此文档

SOLUTION:解决方案:

const CryptoJS = require("crypto-js");

const key = "accesskey";
const version="2020-10-02"
const account = 'storagename'
const containerName = 'containername'
const strTime = (new Date()).toUTCString();

export default async (req, res) => {  
  if (req.method === 'POST') {

    const { blobName } = req.body
    const srcBlobName = blobName
    const srcBlobUrl = `https://${account}.blob.core.windows.net/${containerName}/${srcBlobName}`
    const destBlobName = srcBlobName + 'rHrH'
    const destBlobUrl = `https://${account}.blob.core.windows.net/${containerName}/${destBlobName}`;
    
    const destAccessTier = 'Cool'
    const canonicalizedHeaders = `x-ms-access-tier:${destAccessTier}\nx-ms-copy-source:${srcBlobUrl}\nx-ms-date:${strTime}\nx-ms-version:${version}\n`;
    const canonicalizedResource = `/${account}/${containerName}/${destBlobName}`;
    const strToSign = `PUT\n\n\n\n\n\n\n\n\n\n\n\n${canonicalizedHeaders}${canonicalizedResource}`;
    const secret = CryptoJS.enc.Base64.parse(key);
    const hash = CryptoJS.HmacSHA256(strToSign, secret);
    const hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
    const auth = `SharedKey ${account}:`+hashInBase64;
    
    const PUTconfig = {
    method: 'PUT',
    headers: {
        'x-ms-access-tier': destAccessTier,
        'x-ms-copy-source': srcBlobUrl,
        'x-ms-date': strTime,
        'x-ms-version': version,
        'Authorization': auth
        }
    };

    fetch(destBlobUrl, PUTconfig)
    .then( results => {
        if(results.status==200) {console.log('api works')} else {console.log(results)}},
        res.end()
    )    
  } 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM