rack-cors: rails-api & rails 4 not working with rack-cors?

I’ve added rack-cors to my gemfile and put in my development.rb and production.rb (I also tried application.rb):

  config.middleware.insert_before ActionDispatch::Static, Rack::Cors do
    allow do
      origins '*.example.com'
      resource '*', :headers => :any, :methods => [:get, :post, :options]
    end
  end

When I run rake middleware, I can see Rack::Cors. When I do a curl request for development or production no CORS headers are added to the requests. There’s no errors to try to track, so I’m at a loss for why this isn’t working.

About this issue

  • Original URL
  • State: closed
  • Created 11 years ago
  • Comments: 90 (24 by maintainers)

Commits related to this issue

Most upvoted comments

+1 from me.

Using rack-cors as per the readme in a rails-api project and I see no headers added by the gem if I do a GET. If I do a POST, I can get the headers properly when I tested using the Chrome Postman app.

Code for middleware insertion (copied verbatim from README):

    config.middleware.use Rack::Cors do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end

All headers returned:

Access-Control-Allow-Credentials →true
Access-Control-Allow-Methods →GET, POST, OPTIONS
Access-Control-Allow-Origin →chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Access-Control-Max-Age →1728000
Cache-Control →max-age=0, private, must-revalidate
Content-Type →text/html
ETag →"7215ee9c7d9dc229d2921a40e899ec5f"
Transfer-Encoding →chunked
Vary →Origin
X-Content-Type-Options →nosniff
X-Frame-Options →SAMEORIGIN
X-Request-Id →72f58d72-e89c-48a4-a80e-1f8f52c2b5fe
X-Runtime →0.017717
X-UA-Compatible →chrome=1
X-XSS-Protection →1; mode=block

Environment information:

ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.3.0]

Rails 4.0.0

Darwin A-strong-preference-for-raincoats.local 12.5.0 Darwin Kernel Version 12.5.0: Sun Sep 29 13:33:47 PDT 2013; root:xnu-2050.48.12~1/RELEASE_X86_64 x86_64

Please let me know if I can provide any additional information. Thanks!

So, to summarize: currently the only way to fix this is to use config.middleware.insert_before ActionDispatch::Static, Rack::Cors do and enable config.serve_static_assets in production.rb?

It works, but I really don’t want to enable static assets 😞

I have same problem, but only when running in production mode. For development it works OK. I’m using vanilla Rails 4.

Edit: Ah, I needed to use config.middleware.insert_before ActionDispatch::Static, Rack::Cors do and this to work you need to set config.serve_static_assets = true in production.rb.

I think I met this problem in Rails 5.

Versions:

  • Ruby 2.6.1
  • Rails 5.2.2
  • rack-cors 1.0.2

Server is running under development env.

Results come first, as shown in the picture, I tried two requests with different origins, and the server gave me almost the same response(only with little difference in the headers). image

Server SHOULD give 401, right?

Here’s my config:

# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'foobar.com'

    resource '*',
             headers: :any,
             methods: %i[get post put patch delete options head]
  end
end

Here’re middlewares:

 $ rails middleware
use Rack::Cors
use Raven::Rack
use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use ActionDispatch::RequestId
use ActionDispatch::RemoteIp
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Bullet::Rack
run Hermes::Application.routes

I ran into this problem, turned out it was because I was testing my api with cURL or by hitting the api directly in chrome. In both cases there is no Origin header on the request. Adding the Origin header to my request triggered the response headers to include Access-Control-Allow-Origin: http://127.0.0.1:4200 and etc.

curl -I --header "Origin: http://127.0.0.1:4200" http://localhost:3000/your/path/here

I donno, it’s working for me on Heroku with Rails 4.2.0.beta2, when I configure CORS in a Rackup file, as below.

  • However, this app is API only and not serving any static assets.
  • Also, I’m using the Devise Token Auth gem.
# This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment',  __FILE__)
run Rails.application

cors_origins = ENV.fetch('RAILS42_CORS_ORIGINS', '*')

require 'rack/cors'
use Rack::Cors do
  # TODO: secure
  allow do
    origins cors_origins
    resource '*',
             :headers => :any,
             :expose  => ['access-token', 'expiry', 'token-type', 'uid', 'client'],
             :methods => [:get, :post, :options, :delete, :put]
  end
end

@thebravoman glad that was it.

Looking at the spec, it looks like the Origin header format is <scheme> "://" <hostname> [ ":" <port> ]. Maybe I should automatically strip out any starting slash by default.

@zigomir’s solution works for me, though I tweaked it and I am using config.middleware.insert_after Rails::Rack::Logger, Rack::Cors, :logger => Rails.logger do so that I can get log messages. Has anyone managed to get this working on Heroku?