Search code examples
ruby-on-railscorsamazon-cloudfrontcdn

Rails + Cloudfront - No Access-Control-Allow-Origin header is present


So I've configured my Ruby on Rails app to use CloudFront as a CDN. JavaScript, CSS & image assets seem to be serving correctly via CloudFront but fonts are failing with a CORS issue -

Access to Font at 'https://abcdefghikl.cloudfront.net/assets/fonts/din-regularalternate-webfont-79090091223f0c54d7042ef125ad4f26.ttf' from origin 'https://myapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://myapp.com' is therefore not allowed access.

Any idea how I can fix this?

I have whitelisted the following headers on AWS CloudFront as well. Btw, the fonts are being served from my Rails server (not from S3).

enter image description here


Solution

  • Here's an example Rails 5.2 app that serves a custom font through CloudFront. It runs on Heroku with the Edge addon but applies to any Rails / CloudFront setup.

    https://github.com/nzoschke/edgecors

    First you need to configure CloudFront to forward the browser Origin header.

    Next use the rack-cors gem and add a configuration to your Rails config/application.rb:

    module EdgeCors
      class Application < Rails::Application
        config.middleware.insert_before 0, Rack::Cors do
          allow do
            origins %w[
              http://edgecors.herokuapp.com
              https://edgecors.herokuapp.com
            ]
            resource '/assets/*', headers: :any, methods: [:get, :post, :options]
          end
        end
      end
    end
    

    Change the origin whitelist to your website URL.

    Now requests from https://edgecors.herokuapp.com to a font at https://abcdefghikl.cloudfront.net/assets/fonts/din-regularalternate-webfont-79090091223f0c54d7042ef125ad4f26.ttf will be sent back to the origin Rails app.

    The middleware introspects the Origin header and adds the Access-Control-Allow-Origin: https://edgecors.herokuapp.com header to the response if it is in the whitelist.

    The browser will then happily load the font. And CloudFront will cache.