Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Active Storage - CloudFlare - Image Caching & CDN #9043

Closed
MatthewKennedy opened this issue Oct 14, 2018 · 4 comments
Closed

Active Storage - CloudFlare - Image Caching & CDN #9043

MatthewKennedy opened this issue Oct 14, 2018 · 4 comments

Comments

@MatthewKennedy
Copy link
Contributor

MatthewKennedy commented Oct 14, 2018

This is not really a bug with Spree, more of an issue with image caching and using a CDN for images served through Rails 5.2 Active Storage, but I figured it might be useful to have a documented solution on this issue for other Spree users.

Issue

Active Storage is simple to set up and get working, but offers no out of the box solution for serving your public facing images through a content delivery network or browser caching, with images having a signed link that expires after 5 minutes, this is great for secure files and download paid for content links, but not ideal for real world usage when serving website product images.

Solution

This solution uses CloudFlare for the CDN and caching.

Work Around

With Spree using active_storage/representations to display images you can simply monkey patch the following file in Rails 5.2.1:
rails-5.2.1/activestorage/app/controllers/active_storage/representations_controller.rb

With the following code

# frozen_string_literal: true

# Take a signed permanent reference for a blob representation and turn it into an expiring service URL for download.
# Note: These URLs are publicly accessible. If you need to enforce access protection beyond the
# security-through-obscurity factor of the signed blob and variation reference, you'll need to implement your own
# authenticated redirection controller.
class ActiveStorage::RepresentationsController < ActiveStorage::BaseController
  include ActiveStorage::SetBlob

  def show
    expires_in 5.year, public: true
    variant = @blob.representation(params[:variation_key]).processed
    send_data @blob.service.download(variant.key),
              type: @blob.content_type || DEFAULT_SEND_FILE_TYPE,
              disposition: 'inline'
  end
end

This will then give you Active Storage images served with a public accessible file with a 5 year expire date, if you are running your new Spree app through CloudFlare you can now change your active_storage/* page rule from bypass cache to:

cf

And that should do it, your files will be served through the CloudFlare CDN with browser caching.

Please be aware that this fix may be outdated as Rails updates past version 5.2.1

@rationality6
Copy link

rationality6 commented Feb 7, 2019

This is a nice solution for the X-Amz-Expires problem.

Everything's work fine but

https://www.cobang.net/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBZVk9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--d923fa23d41028e5123dc3cbb5494d244a726df7/download-1.jpg

When first time created It has X-Amz-Expires.

Could anyone help this part?

How to monkey patching with this?

something like

def new
      expires_in 5.year
end

Thank you!

@collimarco
Copy link

I had a similar need for a Rails app and this is my solution: https://stackoverflow.com/a/59107484/51387

@marckohlbrugge
Copy link

For anyone else ending up here through Google, Rails now has supports proxying: https://github.com/rails/rails/blob/master/activestorage/README.md#proxying

For Cloudflare you still need the configuration above.

@glaucocustodio
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants