Next.js服务端调用Azure存储REST API执行Copy Blob From URL报403错误如何解决
Azure存储REST API调用Copy Blob From URL返回403认证错误问题
背景
我基于已有实现方案在Next.js的/pages/api/目录下完成了容器列表的后端功能,该接口可以正常返回200状态码。现在的需求是把存储层为Cool的Blob复制到另一个存储层为Archive的容器中,避免后续下载归档层Blob时需要先修改访问层级的操作。
已做的修改操作
- 待签名字符串构造如下(该部分是最不确定的地方):
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}`
- 参考官方Copy Blob From URL逻辑设置请求头:
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' } }
其中源Blob地址定义如下:
const blobUrl = `https://${account}.blob.core.windows.net/${containerName}/${blobName}`
- 发起请求的逻辑:
fetch(`https://${account}.blob.core.windows.net/${containerName}/${blobName}`, putConfig) .then( results => console.log(results), res.end())
- 报错信息如下:
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. Make sure the value of Authorization header is formed correctly including the signature.', headers: Headers { [Symbol(map)]: [Object: null prototype] }, counter: 0 } }
后续也尝试了添加x-ms-blob-type头的待签名字符串,还是报同样的错误:
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}`;
疑问
这个错误是否和Azure门户上对应Blob资源的访问权限设置有关?该如何修复?
修复方案
首先排除权限配置问题,403报错的核心原因是签名构造错误+参数配置错误,按以下步骤修复即可:
- 先修复变量为空的问题:你报错返回的请求地址是
https://.blob.core.windows.net//,说明account、containerName、blobName三个变量没有正确赋值,先确认这三个变量可以正常拿到有效值。 - 修正请求目标地址:你现在的请求地址是源Blob的地址,相当于要覆盖源文件,不符合你复制到目标Archive容器的需求,把请求地址的
containerName替换为你的目标Archive容器名称。 - 修正待签名字符串:Copy Blob From URL接口要求所有
x-ms-开头的请求头都要按字典序加入待签名字符串,你额外传了x-ms-copy-source和x-ms-requires-sync两个头,必须加到签名里,正确的待签名字符串构造如下:
const strToSign = `PUT\n\n\n\n\n\n\n\n\n\n\n\nx-ms-copy-source:${blobUrl}\nx-ms-date:${strTime}\nx-ms-requires-sync:true\nx-ms-version:2020-10-02\n/${account}/${targetContainerName}/${blobName}`
注意这里的容器名要和请求地址里的目标容器名保持一致。
4. 移除不必要的头:x-ms-blob-type是Put Blob接口需要的参数,Copy Blob From URL不需要,不要加这个头,避免签名校验失败。
按以上步骤修改后即可正常完成跨容器复制操作。
内容的提问来源于stack exchange,提问作者Andres R
相关产品推荐
相关产品推荐

