简体   繁体   English

云前+载波

[英]Cloudfront + Carrierwave

So this seems like it should be quite easy... everyone is saying just to use config.asset_host . 所以这似乎应该很容易...每个人都只是说要使用config.asset_host When I set that though, all the links inside my app still point to S3. 但是,当我设置它时,我的应用程序内的所有链接仍指向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

here is how I call my files... 这是我如何称呼我的文件...

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

It looks to me like public_url prepends the proper host, but it takes 0 arguments... so how am I supposed to pass the proper response-content-disposition and response-content-type and the link expire time? 在我看来, public_url为适当的主机添加了public_url ,但是它使用了0个参数...所以我应该如何传递适当的response-content-dispositionresponse-content-type以及链接到期时间?

I had the same problem and spent far too long figuring out the answer! 我遇到了同样的问题,花了太长时间找出答案! It turns out that when you set fog_public = false CarrierWave will ignore config.asset_host . 原来,当您设置fog_public = false时, CarrierWave将忽略config.asset_host You can demo this by setting config.fog_public = true : your URLs will now be CloudFront URLs rather than S3 URLs. 您可以通过设置config.fog_public = true进行演示:您的URL现在将是CloudFront URL,而不是S3 URL。 This issue has been raised previously: 此问题先前已提出:

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

In a recent project I was happy using CarrierWave to handle uploads to S3, but wanted it to return a signed CloudFront URL when using Model.attribute_url . 在最近的项目中,我很高兴使用CarrierWave处理到S3的上载,但是希望它在使用Model.attribute_url时返回签名的CloudFront URL。 I came up with the following (admittedly ugly) workaround that I hope others can benefit from or improve upon: 我提出了以下(非常丑陋的)解决方法,希望其他人可以从中受益或改进:

Add the 'cloudfront-signer' gem to your project and configure it per the instructions. “ cloudfront-signer” gem添加到您的项目中,并按照说明进行配置。 Then add the following override of /lib/carrierwave/uploader/url.rb in a new file in config/initializers (note the multiple insertions of AWS::CF::Signer.sign_url ): 然后在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

Then override /lib/carrierwave/storage/fog.rb by adding the following to the bottom of the same file: 然后通过将以下内容添加到同一文件的底部来覆盖/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

Lastly, in config/initializers/carrierwave.rb : 最后,在config / initializers / carrierwave.rb中

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

config.fog_public = false config.fog_public =否

That's it. 而已。 You can now use Model.attribute_url and it will return a signed CloudFront URL to a private file uploaded by CarrierWave to your S3 bucket. 现在,您可以使用Model.attribute_url,它将签名的CloudFront URL返回到CarrierWave上传到您的S3存储桶的私有文件中。

I think you found this for yourself, but public urls will not expire. 我想您是自己找到的,但公共网址不会过期。 If you want that you'll need to use authenticated urls. 如果需要,则需要使用经过身份验证的网址。 For public urls I think you can simply get the url and append whatever query params you would like, at least for now. 对于公共URL,我认为您至少可以暂时获取URL并附加所需的任何查询参数。 If that works well for you, we can certainly see about patching things to do the right thing. 如果这对您来说很好,我们当然可以看到打补丁以做正确的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM