node.js - AWS S3 - 从 getSignedUrl() PUT 到 URL 返回 403 SignatureDoesNotMatch 错误
问题描述
这个问题已经让我发疯了两天了。
目标:通过 AWS Javascript SDK 中的 getSignedUrl 函数提供的预签名 URL,将图像直接从浏览器上传到 S3。
使用 getSignedUrl 生成 URL 没有任何问题。以下代码...
const params = {
Key: key,
Bucket: process.env.S3_BUCKET,
ContentType: "image/jpeg"
};
S3.getSignedUrl("putObject", params, callback);
...产生类似的东西:
https://s3.amazonaws.com/foobar-bucket/someImage.jpeg?AWSAccessKeyId=ACCESSKEY123&Content-Type=image%2Fjpeg&Expires=1543357053&Signature=3fgjyj7gpJiQvbIGhqWXSY40JUU%3D&x-amz-acl=private&x-amz-security-token=FQoGZXIvYXdzEDYaDPzeqKMbfgetCcZBaCL0AWftL%2BIT%2BP3tqTDVtNU1G8eC9sjl9unhwknrYvnEcrztfR9%2FO9AGD6VDiDDKfTQ9SmQpfXmiyTKDwAcevTwxeRnj6hGwnHgvzFVBzoslrB8MxrxjUpiI7NQW3oRMunbLskZ4LgvQYs8Rh%2FDjat4H%2F%2BvfPxDSQUSa41%2BFKcoySUHGh2xqfBFGCkHlIqVgk1KELDHmTaNckkvc9B4cgEXmAd3u1f1KC9mbobYcLLRPIzMj9bLJH%2BIlINylzubao1pCQ7m%2BWdX5xAZDhTSNwQfo4ywSWV7kUpbq2dgEriOiKAReEjmFQtuGqYBi3t2dhrasptOlXFXUozdz23wU%3D
但是通过 PUT 请求将图像上传到提供的 URL 总是会403 SignatureDoesNotMatch
从 S3 返回错误。
有什么作用:
- 从 AWS Lambda 的本地实例调用 getSignedUrl()(通过无服务器离线)。
什么不起作用:
- 将查询字符串变量设置为标题(Content-Type、x-amz-* 等)
- 删除所有标题
- 获取 URL 时更改 ACL(私有、公共读写、无 ACL 等)
- 更改
aws-sdk
节点中的区域 - 尝试 POST 而不是 PUT(值得一试)
对此问题的任何帮助将不胜感激。如果这仍然是一个问题,我将把我的电脑扔出窗外并沮丧地跳出来,因为它根本不想工作!
解决方案
我想到了。调用 getSignedUrl() 的 Lambda 函数没有正确的 IAM 角色权限来访问有问题的 S3 存储桶。在 serverless.yml 中...
iamRoleStatements:
- Effect: Allow
Action:
- s3:*
Resource: "arn:aws:s3:::foobar-bucket/*"
我实际上不会在这里使用通配符,但你明白了。即使由于缺少权限而导致 URL 注定失败,getSignedUrl()仍然成功并返回 URL 的事实极具误导性。
我希望这个答案能在未来帮助一些困惑的灵魂。
推荐阅读
- xaml - ScrollView 截断 Xamarin 中的 Grid
- arduino - 与串行编码器的 Arduino 串行通信
- selenium - org.openqa.selenium.StaleElementReferenceException:过时元素引用:元素未附加到页面文档以查找元素
- r - 由于“意外符号”输入而无法获取 GLM
- reactjs - 如何解决以 1 错误退出的命令“yarn run build”!?
- python - 如何生成具有用户输入的位数的随机数?
- python - Python - 单线程执行器已被使用,会死锁
- android-youtube-api - Youtube Android Player API 4k 直播不工作:错误屏幕演示者应该存在
- postgresql - 在 PostgreSQL 上执行查询的表名周围是否必须使用“”?
- java - ZGC是否支持UseGCOverheadLimit?