AWS s3从Rails应用程序访问私有存储桶URL

时间:2018-11-15 00:59:42

标签: ruby-on-rails ruby amazon-web-services amazon-s3 rubyzip

我是RoR的新手。

我正在创建一个上传图像并将其保存在S3中的小型应用程序,用户无法将所有图像附加到zip文件中并通过电子邮件发送,以使用 ruby​​zip gem来实现

在本地运行良好(我遵循gem文档)

https://github.com/rubyzip/rubyzip/

但是在生产“ ZIP”操作时,我需要提供一个源文件夹(在其中保存图像),并且由于我所有的图像都保存在s3存储桶中,因此我给出了如下路径:

folder = 'https://'bucket-name'.s3.amazonaws.com/'

经过研究,我喜欢类似的案例,但是没有一个对我有用,例如,我尝试过 How to retrieve attachment url with Rails Active Storage with S3,它给我“没有这样的文件或目录”

2018-11-15T00:44:27.082416+00:00 app[web.1]: I, [2018-11-15T00:44:27.082337 #4]  INFO -- : [db52fa26-32c2-4f7e-a766-7d39fd3ef062] Completed 500 Internal Server Error in 1532ms (ActiveRecord: 21.4ms)
2018-11-15T00:44:27.082915+00:00 app[web.1]: F, [2018-11-15T00:44:27.082844 #4] FATAL -- : [db52fa26-32c2-4f7e-a766-7d39fd3ef062]
2018-11-15T00:44:27.082988+00:00 app[web.1]: F, [2018-11-15T00:44:27.082916 #4] FATAL -- : [db52fa26-32c2-4f7e-a766-7d39fd3ef062] Errno::ENOENT (No such file or directory @ rb_file_s_lstat - https://bucket-name.s3.amazonaws.com):
2018-11-15T00:44:27.083054+00:00 app[web.1]: F, [2018-11-15T00:44:27.082985 #4] FATAL -- : [db52fa26-32c2-4f7e-a766-7d39fd3ef062]

我的存储桶是私有的,因此,在提供正确的凭据之前,它不允许我访问它,这就是我不知道如何在url中发送签名进行身份验证的部分。 我已经尝试过类似以下的方法,但是它总是给我带来奇怪的辛博尔语

kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + secret_access_key, dateStamp)
    kRegion = OpenSSL::HMAC.digest('sha256', kDate, regionName)
    kService = OpenSSL::HMAC.digest('sha256', kRegion, serviceName)
    signature = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")


    puts("#{s3_base_url}?AWSAccessKeyId=#{access_key_id}
            &Expires=#{expiration_date}
            &Signature=#{signature}")

这是我打印签名时的结果

https://bucket-name.s3.amazonaws.com?AWSAccessKeyId=my-access-key
            &Expires=1542416076
            &Signature=Q�����>�9`o���r}�9��`�m��g��

Ps。我还创建了一个具有管理员权限的IAM用户

谢谢,我使用ruby 2.5.1和rails 5.2.0 我与AMAZON打交道非常新,如果我的问题很明显,请原谅

1 个答案:

答案 0 :(得分:0)

我不确定要手动构造一个签名的URL。我从来没有尝试过。但是,AWS gem具有用于S3对象的presigned_url方法,它将为您构造它们。然后,您可以使用该URL访问私有存储桶中的对象。

请参见https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_url-instance_method

bucket = Aws::S3::Bucket.new bucket_name
object = bucket.object object_key
object.presigned_url(:get, expires_in: expiry)