使用预先签名的网址将其放置到S3会产生403错误 [英] PUT to S3 with presigned url gives 403 error

查看:228
本文介绍了使用预先签名的网址将其放置到S3会产生403错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆