【发布时间】:2020-12-05 17:22:52
【问题描述】:
我的请求如下所示:
https://{my-bucket-name}.s3.amazonaws.com/{user-id}/{image-name}.jpeg?AWSAccessKeyId={key}&Content-Type=image%2Fjpeg&Expires =1597576628&签名={签名}
其中 {parts} 只是被审查,但在原始响应中看起来是正确的,就像在我正在做的教程中一样。
我已允许公共访问并设置了 CORS(这就是我首先获得要上传到的预签名 URL 的原因)以及包含以下内容的存储桶策略:
{
"Sid": "{sid}",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::{my-bucket-name}/*",
"Principal": "*"
}
那么可能是什么问题?
编辑:将 PutObject 添加到策略中没有帮助。我直接从 React-client 上传这样的文件:
const upload = await axios.put(uploadConfig.data.url, file, {
headers: {
'Content-Type': file.type
}
})
然后我生成这样的预签名 URL(注意 putObject 操作):
s3.getSignedUrl('putObject', {
Bucket: '{my-bucket-name}',
ContentType: 'image/jpeg',
Key: key
}, (err, url) => res.send({key, url}));
中间件/浏览器设置的额外请求头有:
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en,de;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 104221
Content-Type: image/jpeg
Host: {my-bucket-name}.s3.amazonaws.com
Origin: http://localhost:3000
Pragma: no-cache
Referer: http://localhost:3000/blogs/new
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla....
【问题讨论】:
-
如何上传带有预签名 url 的文件?
-
@Phil,我已经删除了我的答案。那是错的。因为你永远不应该允许公共写访问。如果用于生成预签名 url 的 IAM 凭证有足够的权限上传文件,则预签名 url 应该也可以工作。
-
另外,如果您的预签名 URL 是为
getObject生成的,则无法使用该预签名 URL 执行putObject操作 -
@ArunK 我正在做这个教程:udemy.com/course/advanced-node-for-developers 老师解释说公共访问是好的,因为我们希望从客户端直接上传,而不浪费后端的 CPU 时间,期间上传。对我来说,这似乎是合理的,只要您只检查文件扩展名并且不进行深度文件检查。
-
我的意思是,为存储桶策略中的每个人授予
putObject权限是不好的。使用预签名的 url 上传是正确的方法。如果您愿意与全世界共享您的文件,那么公开阅读是可以的。
标签: amazon-web-services amazon-s3