我尝试在 Node.js 应用程序中使用适用于 JavaScript 的 AWS 开发工具包 (v3) 列出 Cloudflare R2 存储桶中的对象,但遇到“未经授权”错误。
这是我正在使用的代码片段:
const { S3Client, ListObjectsCommand } = require('@aws-sdk/client-s3');
const s3Client = new S3Client({
endpoint: 'https://<my-r2-subdomain>.r2.cloudflarestorage.com',
credentials: {
accessKeyId: process.env.CLOUDFLARE_ACCESS_KEY_ID,
secretAccessKey: process.env.CLOUDFLARE_SECRET_ACCESS_KEY,
},
signatureVersion: 'v4',
});
const bucketParams = {
Bucket: 'my-bucket-name',
};
const listObjects = async () => {
try {
const data = await s3Client.send(new ListObjectsCommand(bucketParams));
console.log('Success', data);
} catch (err) {
console.error('Error', err);
}
};
listObjects();
我收到以下 401 回复:
{
"$fault": "client",
"$metadata": {
"httpStatusCode": 401,
"requestId": "undefined",
"extendedRequestId": "undefined",
"cfId": "undefined",
"attempts": 1,
"totalRetryDelay": 0
},
"Code": "Unauthorized"
}
错误堆栈跟踪是:
Error Unauthorized: Unauthorized
at throwDefaultError (D:\GitHub\cloudflare-r2-testing\node_modules\@smithy\smithy-client\dist-cjs\default-error-handler.js:8:22)
at D:\GitHub\cloudflare-r2-testing\node_modules\@smithy\smithy-client\dist-cjs\default-error-handler.js:18:39
at de_ListObjectsCommandError (D:\GitHub\cloudflare-r2-testing\node_modules\@aws-sdk\client-s3\dist-cjs\protocols\Aws_restXml.js:5032:20)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async D:\GitHub\cloudflare-r2-testing\node_modules\@smithy\middleware-serde\dist-cjs\deserializerMiddleware.js:7:24
at async D:\GitHub\cloudflare-r2-testing\node_modules\@aws-sdk\middleware-signing\dist-cjs\awsAuthMiddleware.js:14:20
at async D:\GitHub\cloudflare-r2-testing\node_modules\@smithy\middleware-retry\dist-cjs\retryMiddleware.js:27:46
at async D:\GitHub\cloudflare-r2-testing\node_modules\@aws-sdk\middleware-sdk-s3\dist-cjs\region-redirect-endpoint-middleware.js:14:24
at async D:\GitHub\cloudflare-r2-testing\node_modules\@aws-sdk\middleware-sdk-s3\dist-cjs\region-redirect-middleware.js:9:20
at async D:\GitHub\cloudflare-r2-testing\node_modules\@aws-sdk\middleware-logger\dist-cjs\loggerMiddleware.js:7:26
我已确认:
Cloudflare R2 访问密钥 ID 和秘密访问密钥正确且有效
令牌对所有存储桶具有管理员读写权限
没有激活代理或防火墙
环境变量已正确加载到 Node.js 进程中
问题是什么?
您需要指定一个区域,特别是 CloudFlare R2 区域。
CloudFlare R2 区域与 AWS S3 区域不同。如果您没有为客户端手动指定 R2 区域,则使用
aws configure
、计算机上存在“~/.aws/config”文件或 其他配置选项等操作可能会导致您的客户端使用AWS 区域。
这些 AWS 区域与 CloudFlare R2 不兼容,因此您需要确保在凭证提供商链中的某个时刻,您的 AWS SDK 客户端使用 R2 区域。
根据 CloudFlare 文档,有效值为:
auto
:根据呼叫者位置自动选择最近的区域wnam
:北美西部enam
:北美东部weur
:西欧eeur
:东欧apac
:亚太地区像这样指定区域:
const s3Client = new S3Client({
endpoint: 'https://${ACCOUNT_ID}.r2.cloudflarestorage.com',
region: "{REGION}",
credentials: {
accessKeyId: process.env.CLOUDFLARE_ACCESS_KEY_ID,
secretAccessKey: process.env.CLOUDFLARE_SECRET_ACCESS_KEY,
},
signatureVersion: 'v4',
});
作为旁注,
此操作已修改。我们建议您在开发应用程序时
使用较新的版本ListObjectsV2
。为了向后兼容,Amazon S3 继续支持 ListObjects。
ListObjectsV2Command
进行新应用。