我的代码如下所示:
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]
。
我想使用此存储桶作为虚拟形象的存储空间,因此每个人都应该能够随时查看链接的图片。任何想法如何获得永久不会过期的永久性网址,也不会在一年内到期?
答案 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
否则正在设置私人权限。