【问题标题】:How to do a Pre-signed POST file upload to AWS S3 in Ruby?如何在 Ruby 中将预签名的 POST 文件上传到 AWS S3?
【发布时间】:2015-11-29 10:49:47
【问题描述】:

my question about the same thing in Go相关。

我想将预签名的 POST 文件上传到 AWS S3 上的存储桶,该存储桶仅具有以下存储桶策略的公共读取:

{
    "Version": "2012-10-17",
    "Id": "Policy1441191234567",
    "Statement": [
        {
            "Sid": "Stmt1441195123456",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mytestbucket/*"
        }
    ]
}

一个预签名的 URL 被创建,允许任何拥有它的人使用 HTTP POST 进行上传,如 here 所述。

我已成功使here 中描述的预签名 PUT 工作。 IE。我在 ~/aws/credentials 中有正确的凭据,可以完全访问存储桶。

AWS Ruby SDK中,我发现bucket有一个PresignedPost,所以我尝试了以下方法:

require 'aws-sdk-resources'
require 'net/http'
require 'time'
require 'uri'

s3 = Aws::S3::Resource.new(region:'eu-central-1')

bucket = s3.bucket('mytestbucket')

post = bucket.presigned_post({
    key: 'larry',
    acl: "public-read",
    expires: Time.now() + 30,
    content_length_range: 1...1024,
    success_action_redirect: "https://example.com/callback",
})

puts post.url
puts post.fields

uri = URI(post.url)
fields = post.fields.merge(file: "ken sent me")
res = Net::HTTP.post_form(uri, fields)
puts res.body

不幸的是,运行它会导致错误:

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>InvalidArgument</Code><Message>Conflicting query string parameters: acl, policy</Message><ArgumentName>ResourceType</ArgumentName><ArgumentValue>acl</ArgumentValue><RequestId>6132C47A14212345</RequestId><HostId>abcdKciFUKxvC4717Zm9w2ZB5lXJna+NSkxXzkb9123tjHZHb60JJa123KctSu862gY/j+a5+3w=</HostId></Error>

我已尝试删除 acl 字段,但这会导致另一个错误:

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>MethodNotAllowed</Code><Message>The specified method is not allowed against this resource.</Message><Method>POST</Method><ResourceType>BUCKETPOLICY</ResourceType><RequestId>9B3D7AAAE45BB47F</RequestId><HostId>yk823Z12345uucETlpQaG1234T0lxqjGAX4Uka123LQ6Pf22NVf45xxMmZAlFoQHaP+C4N60oLI=</HostId></Error>

URI 是:https://mytestbucket.s3.eu-central-1.amazonaws.com

有什么问题,我该如何解决?

感谢您的帮助!

更新

正如其中一个错误所说,问题可能是 acl 和存储桶策略冲突。我希望所有人都可以阅读它,并且只能使用预签名的 URL 上传(我假设所有者成为创建 URL 的人)。我以为我就是这样设置的。

【问题讨论】:

  • @murrekattt 你最后用了什么,为什么?

标签: ruby file-upload amazon-s3 http-post pre-signed-url


【解决方案1】:

我认为这里有多种策略在起作用。 bucket policypost policy。另请参阅PresignedPost 上的 Ruby 文档——您必须搜索“发布策略”,因为我可以看到标题没有锚点。看起来 Ruby 为您创建了一个发布策略,但是:

您必须指定将由浏览器发布的每个表单字段名称。如果您省略浏览器发送的表单字段,Amazon S3 将拒绝该请求。

此外,提供的PresignedPost 似乎是为了生成一个 HTML 表单,该表单又生成 POST 请求和 URL。你可以生成它而不是让表单来做。但是,如果您已经知道 URL 和请求的所有详细信息——正如 your Go question about the same thing 中所问的那样——为什么不知道 Upload an Object Using a Pre-Signed URL

【讨论】:

  • 预签名 URL 和预签名 POST 是两个不同的东西。前者过​​于简单,没有与后者相同的约束。
  • @murrekatt 您能否详细说明它们的基本区别?
【解决方案2】:

所以我有updated the Go question with an answer,这同样适用于 Ruby。我遇到的问题是正确生成多部分表单数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-23
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    相关资源
    最近更新 更多