CORS headers in Rails stack ?

When working with API which is bombarded by XHR requests, which often come from various subdomains, one turns CORS headers.

Common solution for most of Rails developers is to create before_action with custom headers.

def enable_cross_resource sharing
  headers['Access-Control-Allow-Origin'] = '*'
  headers['Access-Control-Allow-Headers'] = 'GET, POST, PUT, DELETE, OPTIONS'
  headers['Access-Control-Allow-Methods'] = 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'

This is an alright solution but I’d suggest moving that into a (Rack)[] middleware layer before your Rails router kicks in. Issue with the controller method is that you must enable OPTIONS response in the rails router to handle requests.

If you don’t want to write your own middleware, Rack Cors comes quite handy.

In application.rb make sure that you serve CORS at the top of the stack or at least before middleware you need (in my case I had Warden::Manager instead of 0).

config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'
    resource '*',
      :headers => :any,
      :methods => [:get, :post, :delete, :put, :options, :head]

That’s an ‘OK’ setup for Heroku, (Aptible)[] or other services, which allow you to deploy your app with cli but won’t let you access higher stack like Nginx or Apache

The proper way of handling Cross-origin is to set it up at the Nginx/Load-balancer level. So your Rails app is only busy with serving text but not the headers.

For NGINX you can make use of add_header in the location context (or server if all your server does is serving API)

add_header Access-Control-Allow-Headers "X-Requested-With";
add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS";
add_header Access-Control-Allow-Origin "*";

Phoenix On A Raspberry Pi with Exrm

## Intro> Before you read this be sure to look at:>> 1. [Phoenix Advanced Deployment](… Continue reading