如何使用带有Rails Active Storage的S3检索附件URL

Sha*_*ani 11 ruby-on-rails amazon-s3 rails-activestorage

rails version 5.2
Run Code Online (Sandbox Code Playgroud)

我有一个场景,我需要使用亚马逊s3访问Rails Active Storage的公共URL来制作带Sidekiq后台作业的zip文件.

我很难获得实际的文件网址.我试过以下

rails_blob_url
Run Code Online (Sandbox Code Playgroud)

但它让我跟随

http://localhost:3000/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBZUk9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--9598613be650942d1ee4382a44dad679a80d2d3b/sample.pdf
Run Code Online (Sandbox Code Playgroud)

如何通过sidekiq访问真实文件网址?

storage.yml

 test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

development:
  service: S3
  access_key_id: 'xxxxx'
  secret_access_key: 'xxxxx'
  region: 'xxxxx'
  bucket: 'xxxxx'
Run Code Online (Sandbox Code Playgroud)

development.rb

  config.active_storage.service = :development
Run Code Online (Sandbox Code Playgroud)

我可以在web界面上访问这些,但不能在sidekiq中访问

Geo*_*orn 35

使用ActiveStorage::Blob#service_url.例如,假设一个Post附加单个模型header_image:

@post.header_image.service_url
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回答.我习惯使用回形针,所以我试图降低Active Storage.实施了具有Active Storage的S3解决方案,效果很好.但是,这个解决方案是说它是一个临时URL?你知道如何获得图像的永久URL吗?可以使用Active Storage吗?回形针仅返回默认的永久URL,因此我期待与Active Storage类似的东西 (5认同)
  • 但不适用于“磁盘”存储本地 (2认同)
  • 这似乎不会创建公共URL?我得到'请求特定的响应头不能用于来自亚马逊的匿名GET请求 (2认同)

Aiv*_*oss 10

如果您需要公开所有文件,则必须公开您的上传:

在文件 config/storage.yml 中

amazon:
  service: S3
  access_key_id: zzz
  secret_access_key: zzz
  region: zzz
  bucket: zzz
  upload:
    acl: "public-read"

Run Code Online (Sandbox Code Playgroud)

在代码中

attachment = ActiveStorage::Attachment.find(90)
attachment.blob.service_url # returns large URI
attachment.blob.service_url.sub(/\?.*/, '') # remove query params
Run Code Online (Sandbox Code Playgroud)

它会返回类似于:“ https://foo.s3.amazonaws.com/bar/buz/2yoQMbt4NvY3gXb5x1YcHpRa

由于上面的配置,它是公开可读的。


gen*_*abs 5

我的用例是将图像上传到S3,该桶可以对存储桶中的所有图像进行公共访问,因此无论请求的来源或URL到期如何,作业都可以在以后拾取它们。这就是我做的。(导轨5.2.2)

首先,新S3的默认设置是将所有内容保密,因此要失败则有2个步骤。

  1. 添加通配符存储区策略。在AWS S3中>>您的存储桶>>权限>>存储桶策略
{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)
  1. 在您的存储桶>>权限>>公共访问设置中,请确保Block public and cross-account access if bucket has public policies将其设置为false

现在,您只需使用blob.keyurl 就可以访问S3存储桶中的任何内容。不再需要过期的令牌。

其次,要生成该URL,您可以使用@Christian_Butzke的解决方案: @post.header_image.service.send(:object_for, @post.header_image.key).public_url

但是,请知道object_for是上的私有方法service,并且如果使用public_send进行调用会给您带来错误。因此,另一种替代方法是使用每个@George_Claghorn的service_url并使用删除任何参数url&.split("?")&.first。如前所述,这可能在localhost中失败,并出现主机丢失错误。

这是我的解决方案,或者是一个可上传的“徽标”,存储在S3上,默认情况下是公开的:

#/models/company.rb
has_one_attached :logo
def public_logo_url
    if self.logo&.attachment
        if Rails.env.development?
            self.logo_url = Rails.application.routes.url_helpers.rails_blob_url(self.logo, only_path: true)
        else
            self.logo_url = self.logo&.service_url&.split("?")&.first
        end
    end
    #set a default lazily
    self.logo_url ||= ActionController::Base.helpers.asset_path("default_company_icon.png")
end
Run Code Online (Sandbox Code Playgroud)

享受^ _ ^