如何在Ruby中将预签名的POST文件上载到AWS S3?

如何在Ruby中将预签名的POST文件上载到AWS S3?,ruby,file-upload,amazon-s3,http-post,pre-signed-url,Ruby,File Upload,Amazon S3,Http Post,Pre Signed Url,与……有关 我想在AWS S3上进行预签名后文件上传到bucket,该bucket仅具有以下bucket策略的公共读取功能: { "Version": "2012-10-17", "Id": "Policy1441191234567", "Statement": [ { "Sid": "Stmt1441195123456", "Effect": "Allow", "Principal"

与……有关

我想在AWS S3上进行预签名后文件上传到bucket,该bucket仅具有以下bucket策略的公共读取功能:

{
    "Version": "2012-10-17",
    "Id": "Policy1441191234567",
    "Statement": [
        {
            "Sid": "Stmt1441195123456",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mytestbucket/*"
        }
    ]
}
创建了一个预签名URL,允许任何拥有它的人使用HTTP POST进行上传,如所述

我已成功地将所述的预签名投入工作。也就是说,我在
~/aws/credentials
中有正确的凭证,可以完全访问存储桶

在中,我发现有一个用于存储桶的方法,因此我尝试了以下方法:

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和bucket策略冲突。我希望它能被所有人阅读,并且只能通过一个预先签名的URL上传(我假设所有者就是创建URL的人)。这就是我设置它的方式。

我认为这里有多种逻辑。这个和那个。另请参阅上的Ruby文档——您必须搜索“Post Policy”,因为我看不到标题的锚。看起来Ruby为您创建了一个post策略,但是:

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


此外,它似乎是为了生成一个HTML表单,然后生成POST请求和URL。您可以生成它,而不是让表单来做。但是,如果您已经知道URL和请求的所有详细信息——如中所述——为什么不知道呢。

我已经知道了,Ruby也是如此。我遇到的问题是正确生成多部分表单数据。

预签名URL和预签名POST是两件不同的事情。前者过于简单,没有与后者相同的约束条件。@murrekatt你能详细说明一下它们的基本区别吗?@murrekatt你最终使用了什么,为什么?