如何S3与CloudFront的工作目标网址是什么?目标、网址、工作、CloudFront

2023-09-11 08:50:26 作者:冷酷帅气的 冷酷无情的昵称

我目前存储的文件私自在S3上。在我的Rails应用程序,在attachment.rb模式,我可以为私人文件,像这样获得的公共网址:

I'm currently storing files privately on S3. In my rails app, in the attachment.rb model I can obtain a public URL for the private file like so:

def cdn_url ( style='original' )
  attachment.s3_object(style).url_for( :read, secure: true, response_content_type: self.meta['file_content_type'], expires: 1.hour ).to_s
end

现在的问题是,这是提供一个URL到S3和重写用我的Cloudfront源URL网址的示数有:

The problem is this is providing a URL to S3 and rewriting the URL to use my Cloudfront origin url is erroring with:

"The request signature we calculated does not match the signature you provided. Check your key and signing method."

我怎样才能得到公众的URL资产中包含但通过的Cloudfront服务资产?

How can I get a public URL asset like below but serve the asset via Cloudfront?

感谢

推荐答案

只需使用 aws_cf_signer 宝石。把它放在你打捆。

First Way (Easy)

Just use aws_cf_signer gem. Put it in you bundler.

有了这个,你可以这样做

WIth this you can do something like

def cdn_url (options = {})
  style = options[:style] || 'original'
  cloudfront_domain =  options[:cloudfront_domain] || 'example.cloudfront.net'
  cloudfront_pem_key_path = options[:cloudfront_pem_key_path]
  cloudfront_key_paid_id = options[:cloundfrount_key_paid_id] 
  path = attachment.path(style)  #path of the file
  # you can get this values from your aws a/c , most probably by going int 
  # https://console.aws.amazon.com/iam/home?#security_credential      
  signer = AwsCfSigner.new(cloudfront_pem_key_path, cloudfront_key_paid_id)
  # this configuration may vary. 
  # visit https://github.com/dylanvaughn/aws_cf_signer 
  # and check all available settings/options   
  url = signer.sign(path, :ending => Time.now + 3600)
  cloudfront_domain + url
end 

通过这个,你可以访问URL像这样

With this you can access the url with something like this

  cdn_url(cloudfront_pem_key_path: '/users/downloads/pri.pem' , cloudfront_key_paid_id: '33243424XXX')

方式二

# A simple function to return a signed, expiring url for Amazon Cloudfront. 
# This will require openssl, digest/sha1, base64 and maybe other libraries. 

module CloudFront
  def get_signed_expiring_url(domain,path, expires_in, private_key_filename, key_pair_id)

    # AWS works on UTC, so make sure you are not using local time
    expires = (Time.now.getutc + expires_in).to_i.to_s

    private_key = OpenSSL::PKey::RSA.new(File.read(private_key_filename))

    # path should be your S3 path without a leading slash and without a file extension.
    # e.g. files/private/52
    policy = %Q[{"Statement":[{"Resource":"#{path}","Condition":{"DateLessThan":{"AWS:EpochTime":#{expires}}}}]}]
    signature = Base64.strict_encode64(private_key.sign(OpenSSL::Digest::SHA1.new, policy))

    # I'm not sure exactly why this is required, but it's in Amazon's perl script and seems necessary
    # Different base64 implementations maybe? 
    signature.tr!("+=/", "-_~")

    "#{domain}#{path}?Expires=#{expires}&Signature=#{signature}&Key-Pair-Id=#{key_pair_id}"
  end
end

有了这个,你可以这样做

With this you can do something like

def cdn_url ( style='original',cloudfront_pem_key_path,key_pair_id)
  path = attachment.path(style)  #path of the file
  # you can get this values from your aws a/c , most probably by going int 
  CloudFront.get_signed_expiring_url 'example.cloudfront.net', path, 45.seconds ,'/users/downloads/pri.pem', 'as12XXXXX')
end

给一个尝试,可能它会奏效。一定要正确设置正确斗访问策略。检查了这一点,如果你看到 accessDenied 错误的 http://www.jppinto.com/2011/12/access-denied-to-file-amazon-s3-bucket/