【问题标题】:Cloudfront + CarrierwaveCloudfront + 载波
【发布时间】:2013-10-18 19:56:07
【问题描述】:

所以这看起来应该很容易......每个人都说只使用config.asset_host。但是,当我设置它时,我的应用程序中的所有链接仍然指向 S3。

CarrierWave.configure do |config|

  config.storage = :fog

  config.fog_credentials = {
    :provider              => 'AWS',
    :aws_access_key_id     => AWS_ACCESS_KEY_ID,
    :aws_secret_access_key => AWS_SECRET_ACCESS_KEY,
    :region                => 'us-east-1'
  }

  config.fog_authenticated_url_expiration = 3.hours

  config.asset_host     = "http://xyz123.cloudfront.net"
  config.fog_directory  = S3_BUCKET_NAME
  config.fog_public     = false
  config.fog_attributes = {
    'Cache-Control' => "max-age=#{1.year.to_i}"
  }
end

这是我如何称呼我的文件...

image_tag book.attachments.first.filename.file.authenticated_url(:thumb175)

在我看来,public_url 预置了正确的主机,但它需要 0 个参数...那么我应该如何传递正确的 response-content-dispositionresponse-content-type 以及链接过期时间?

【问题讨论】:

    标签: ruby-on-rails amazon-web-services ruby-on-rails-4 carrierwave fog


    【解决方案1】:

    我遇到了同样的问题,但花了太长时间才找到答案!事实证明,当您设置 fog_public = false 时,CarrierWave 将忽略 config.asset_host。您可以通过设置 config.fog_public = true 进行演示:您的 URL 现在将是 CloudFront URL,而不是 S3 URL。此问题之前已提出:

    https://github.com/carrierwaveuploader/carrierwave/issues/1158 https://github.com/carrierwaveuploader/carrierwave/issues/1215

    在最近的一个项目中,我很高兴使用 CarrierWave 处理上传到 S3,但希望它在使用 Model.attribute_url 时返回签名的 CloudFront URL。我想出了以下(诚然丑陋的)解决方法,希望其他人可以从中受益或改进:

    'cloudfront-signer' gem 添加到您的项目中并按照说明进行配置。然后在 config/initializers 的新文件中添加以下对 /lib/carrierwave/uploader/url.rb 的覆盖(注意 AWS:: 的多次插入: CF::Signer.sign_url):

    module CarrierWave
          module Uploader
            module Url
              extend ActiveSupport::Concern
              include CarrierWave::Uploader::Configuration
              include CarrierWave::Utilities::Uri
    
              ##
              # === Parameters
              #
              # [Hash] optional, the query params (only AWS)
              #
              # === Returns
              #
              # [String] the location where this file is accessible via a url
              #
              def url(options = {})
                if file.respond_to?(:url) and not file.url.blank?
                  file.method(:url).arity == 0 ? AWS::CF::Signer.sign_url(file.url) : AWS::CF::Signer.sign_url(file.url(options))
                elsif file.respond_to?(:path)
                  path = encode_path(file.path.gsub(File.expand_path(root), ''))
    
                  if host = asset_host
                    if host.respond_to? :call
                      AWS::CF::Signer.sign_url("#{host.call(file)}#{path}")
                    else
                      AWS::CF::Signer.sign_url("#{host}#{path}")
                    end
                  else
                    AWS::CF::Signer.sign_url((base_path || "") + path)
                  end
                end
              end
    
            end # Url
         end # Uploader
    end # CarrierWave
    

    然后通过将以下内容添加到同一文件的底部来覆盖 /lib/carrierwave/storage/fog.rb

    require "fog"
    
    module CarrierWave
      module Storage
        class Fog < Abstract
           class File
              include CarrierWave::Utilities::Uri
              def url
                 # Delete 'if statement' related to fog_public
                 public_url
              end
           end
        end
      end
    end
    

    最后,在 config/initializers/carrierwave.rb

    config.asset_host = "http://d12345678.cloudfront.net"

    config.fog_public = false

    就是这样。您现在可以使用 Model.attribute_url,它会将签名的 CloudFront URL 返回到由 CarrierWave 上传到您的 S3 存储桶的私有文件。

    【讨论】:

      【解决方案2】:

      我想您是自己找到的,但公共网址不会过期。如果您愿意,您需要使用经过身份验证的网址。对于公共网址,我认为您可以简单地获取网址并附加您想要的任何查询参数,至少现在是这样。如果这对您很有效,我们当然可以了解如何通过修补来做正确的事情。

      【讨论】:

        猜你喜欢
        • 2011-09-18
        • 1970-01-01
        • 2011-09-07
        • 2012-12-22
        • 2015-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-05
        相关资源
        最近更新 更多