Rack::Cors
provides support for Cross-Origin Resource Sharing (CORS) for Rack compatible web applications.
The CORS spec allows web applications to make cross domain AJAX calls without using workarounds such as JSONP. See Cross-domain Ajax with Cross-Origin Resource Sharing
Install the gem:
gem install rack-cors
Or in your Gemfile:
gem 'rack-cors', :require => 'rack/cors'
In config.ru
, configure Rack::Cors
by passing a block to the use
command:
use Rack::Cors do
allow do
origins 'localhost:3000', '127.0.0.1:3000',
/http:\/\/192\.168\.0\.\d{1,3}(:\d+)?/
# regular expressions can be used here
resource '/file/list_all/', :headers => 'x-domain-token'
resource '/file/at/*',
:methods => [:get, :post, :put, :delete, :options],
:headers => 'x-domain-token',
:expose => ['Some-Custom-Response-Header'],
:max_age => 600
# headers to expose
end
allow do
origins '*'
resource '/public/*', :headers => :any, :methods => :get
end
end
Put something like the code below in config/application.rb
of your Rails application. For example, this will allow GET, POST or OPTIONS requests from any origin on any resource.
module YourApp
class Application < Rails::Application
# ...
config.middleware.insert_before 0, "Rack::Cors" do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :options]
end
end
end
end
Refer to rails 3 example and rails 4 example for more details.
See The Rails Guide to Rack for more details on rack middlewares or watch the railscast
- debug (boolean): Enables debug logging and
X-Rack-CORS
HTTP headers for debugging. - logger (Object or Proc): Specify the logger to log to. If a proc is provided, it will be called when a logger is needed (this is helpful in cases where the logger is initialized after
Rack::Cors
is used, likeRails.logger
.
Origins can be specified as a string, a regular expression, or as '*' to allow all origins.
A Resource path can be specified as exact string match (/path/to/file.txt
) or with a '*' wildcard (/all/files/in/*
). A resource that take the following options:
- methods (string or array): The HTTP methods allowed for the resource.
- headers (string or array or
:any
): The HTTP headers that will be allowed in the CORS resource request. Use:any
to allow for any headers in the actual request. - expose (string or an array): The HTTP headers in the resource response can can be exposed to the client.
- credentials (boolean): Sets the
Access-Control-Allow-Credentials
response header. - max_age (number): Sets the
Access-Control-Max-Age
response header.
Incorrect positioning of Rack::Cors
in the middleware stack can produce unexpected results. The Rails example above will put it above all middleware which should cover most issues.
Here are some common cases:
-
Serving static files. Insert this middleware before
ActionDispatch::Static
so that static files are served with the proper CORS headers (see note below for a caveat). NOTE: that this might not work in production environments as static files are usually served from the web server (Nginx, Apache) and not the Rails container. -
Caching in the middleware. Insert this middleware before
Rack::Cache
so that the proper CORS headers are written and not cached ones. -
Authentication via Warden Warden will return immediately if a resource that requires authentication is accessed without authentication. If
Warden::Manager
is in the stack beforeRack::Cors
, it will return without the correct CORS headers being applied, resulting in a failed CORS request. Be sure to insert this middleware before 'Warden::Manager`.
To determine where to put the CORS middleware in the Rack stack, run the following command:
bundle exec rake middleware
In many cases, the Rack stack will be different running in production environments. For example, the ActionDispatch::Static
middleware will not be part of the stack if config.serve_static_assets = false
. You can run the following command to see what your middleware stack looks like in production:
bundle exec RAILS_ENV=production rake middleware