使用预先签名的网址将其放置到S3会产生403错误 [英] PUT to S3 with presigned url gives 403 error
问题描述
我正在使用Node获取S3的presignedRUL,以便将图像放入S3存储桶中.
I'm using Node to get an presignedRUL for S3 in order to PUT an image to an S3 bucket.
var aws = require('aws-sdk');
// Request presigned URL from S3
exports.S3presignedURL = function (req, res) {
var s3 = new aws.S3();
var params = {
Bucket: process.env.S3_BUCKET,
Key: '123456', //TODO: creat unique S3 key
//ACL:'public-read',
ContentType: req.body['Content-Type'], //'image/jpg'
};
s3.getSignedUrl('putObject', params, function(err, url) {
if(err) console.log(err);
res.json({url: url});
});
};
此操作成功检索了格式为...的预签名网址.
This successfully retrieves a presigned url of form...
https://[my-bucket-name].s3.amazonaws.com/1233456?AWSAccessKeyId=[My-ID]&Expires=1517063526&Signature=95eA00KkJnJAgxdzNNafGJ6GRLc%3D (Do I have to include an expires header?)
回到客户端(Web应用程序),我使用angular来生成HTTP请求.我曾经用过$ http和ngFileUpload,但都缺少类似的成功.这是我的ngFileUpload代码.
Back on the client side (web app) I use angular to generate an HTTP request. I have used both $http and ngFileUpload, with similar lack of success. Here is my ngFileUpload code.
Upload.upload({
url: responce.data.url, //S3 upload url including bucket name
method: 'PUT',
'Content-Type': file.type, //I have tried putting the ContentTyep header all over
headers: {
//'x-amz-acl':'public-read',
'Content-Type': file.type,
},
data: {
file: file,
headers:{'Content-Type': file.type,}
},
})
但是,似乎无论我如何格式化标题,我总是会收到403错误.在错误的XML中,
However, seemingly regardless of how I format my header I always get a 403 error. In the XML of the error it says,
SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.
我不认为CORS是个问题.最初,我遇到了一些CORS错误,但它们看起来有所不同,并且通过对S3存储桶CORS设置进行了一些更改,使它们消失了.我已经为presignedURL请求和对S3的PUT请求尝试了很多标头的试验和错误设置,但是我似乎找不到正确的组合.
I don't think CORS is an issue. Originally I was getting some CORS errors but they looked different and I got them to go away with some changes to the S3 bucket CORS settings. I've tried a lot of trial and error setting of the headers for both the request for the presignedURL and PUT request to S3, but I can't seem to find the right combo.
我确实注意到,当我console.log 403响应错误时,字段
I did notice that when I console.log the 403 response error, the field
config.headers:{Content-Type: undefined, __setXHR_: ƒ, Accept: "application/json, text/plain, */*"}
这是否表示未设置Content-Type头?当我在所有可能的地方都设置了标头时,该怎么办?无论如何,我的头一直撞在墙上……
Is this saying that the Content-Type head isn't set? How can that be when I've set that header everywhere I can think possible? Anyways, been banging my head against the wall of this for a bit...
根据要求,我当前的CORS. (我投入了所有精力以摆脱之前的CORS警告.只有在上传成功后,我才会将其缩减为基本要求.)
as requested, my Current CORS. (I threw everything in to get rid of the CORS warnings I had earlier. I will pare it down to the essentials only after I get my uploads working.)
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedOrigin>http://localhost:9500</AllowedOrigin>
<AllowedOrigin>https://localhost:9500</AllowedOrigin>
<AllowedOrigin>http://www.example.com</AllowedOrigin>
<AllowedOrigin>https://www.example.com</AllowedOrigin>
<AllowedOrigin>http://lvh.me:9500</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<ExposeHeader>ETag</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
<AllowedHeader>Content-Type</AllowedHeader>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
推荐答案
遇到了同样的问题.发现我用来创建预签名URL的内容类型与我发送给S3的对象的内容类型不匹配.我建议您在创建预签名的URL时添加Expiration标头(我也这样做),并在控制台中准确检查在对S3进行放置时要发送的内容类型.另外,数据只需要是文件,而不是您在那里创建的结构.
Faced the same issue. Found out that the content-type that I used to create the pre-signed URL was not matching the content-type of the object I was sending to S3. I would suggest you add Expiration header when creating the pre-signed URL (I did too) and check in the console exactly what the content-type is being sent when you do a put to S3. Also, the data just needs to be the file, and not the struct you've created there.
这篇关于使用预先签名的网址将其放置到S3会产生403错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!