获取非过期的永久亚马逊s3对象网址

时间:2015-09-20 12:00:44

标签: ruby-on-rails ruby amazon-s3

我的代码如下所示:

module Operations
  class UploadFileToS3 < MethodStruct.new(:params)
    def call
      s3 = Aws::S3::Resource.new(region: ENV['S3_REGION'])
      obj = s3.bucket(ENV['S3_BUCKET_NAME']).object(object_name)
      obj.upload_file(params[:tempfile_path],
                      content_type: params[:content_type],
                      acl: 'public-read')
      {
        url: obj.presigned_url(:get),
        # url: obj.public_url,
        filename: object_name
      }
    end

    private

    def object_name
      "#{params[:timestamp]}-#{params[:uuid]}#{params[:thumbname_suffix]}"
    end
  end
end

对于所有上传的文件,将自动设置以下属性:

Expiry Date: None
Expiration Rule: N/A

上传的对象的Permissions包括:

Everyone: Open/Download

Bucket Permissions包括:

Everyone: View Permissions

Bucket政策如下所示:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<BUCKETNAME>/*"
        }
    ]
}    

注释掉obj.public_url返回对象的裸链接(没有附加查询字符串),它也会过期,然后呈现xml文件。直接从对象道具中获取的裸链接也会过期,即使我手动添加到对象的Permissions

Everyone: View Permissions

即使我通过AWS控制台公开对象,它给我的链接也包含标题X-Amz-Expires=300

尝试使用obj.presigned_url(:get, acl: 'public-read')投掷ArgumentError - unexpected value at params[:acl]

我想使用此存储桶作为虚拟形象的存储空间,因此每个人都应该能够随时查看链接的图片。任何想法如何获得永久不会过期的永久性网址,也不会在一年内到期?

2 个答案:

答案 0 :(得分:5)

如果对象的ACL为public-read,则对象的非过期URL就是:

http[s]://bucket-name.s3.amazonaws.com/path/to/file.ext
  

指向对象的裸链接(未附加查询字符串),也会过期,然后呈现xml文件

不,它没有。您在观察中发生了错误,或者您正在查看缓存的响应。没有查询字符串的URL没有可能导致其过期的机制。请注意xml中的RequestId和HostId。如果它们没有改变,那么您正在处理缓存的响应,因为它们总是从响应变为S3的响应。

答案 1 :(得分:1)

您需要指定acl,例如public_read可以是符号或字符串

  obj.upload_file(params[:tempfile_path],
                  content_type: params[:content_type],
                  acl: :public_read)
  {
    url: obj.public_url,
    filename: object_name
  }

更新了代码

obj = s3.bucket(ENV['S3_BUCKET_NAME']).object(object_name)
obj.write(:file => image_location)
obj.acl = :public_read
obj.public_url.to_s

否则正在设置私人权限。