通过CORS政策允许任何内容


100

如何禁用cors?出于某种原因,我通配了允许的来源和标头,但我的ajax请求仍然抱怨我的CORS策略不允许该来源...。

我的应用程序控制器:

class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :current_user, :cors_preflight_check
  after_filter :cors_set_access_control_headers

# For all responses in this controller, return the CORS access control headers.

def cors_set_access_control_headers
  headers['Access-Control-Allow-Origin'] = '*'
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
  headers['Access-Control-Allow-Headers'] = '*'
  headers['Access-Control-Max-Age'] = "1728000"
end

# If this is a preflight OPTIONS request, then short-circuit the
# request, return only the necessary headers and return an empty
# text/plain.

def cors_preflight_check
  if request.method == :options
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
    headers['Access-Control-Allow-Headers'] = '*'
    headers['Access-Control-Max-Age'] = '1728000'
    render :text => '', :content_type => 'text/plain'
  end
end
  private
  # get the user currently logged in
  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
  helper_method :current_user

end

路线:

  match "*all" => "application#cors_preflight_check", :constraints => { :method => "OPTIONS" }
  match "/alert" => "alerts#create"
  match "/alerts" => "alerts#get"
  match "/login" => "sessions#create"
  match "/logout" => "sessions#destroy"
  match "/register" => "users#create"

编辑 - -

我也尝试过:

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

在application.rb中

-编辑2 ---

问题是我认为Chrome扩展程序可能不支持CORS。如何绕过CORS获取信息?我应该如何应对飞行前检查?


1
不是“禁用CORS”但实际上没有政策?我似乎无法回应任何要求。
不符合规定的人

1
您是否在localhost上使用它?
Dzung Nguyen

Answers:


154

对于使用rails-api的公共API,我有相同的要求。

我还在前过滤器中设置了标头。看起来像这样:

headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'

看来您错过了Access-Control-Request-Method标头。


那很奇怪。您能否提供有关错误的更多信息?
matteo

github.com/cleor41/Cors-Rails4-API如果您不知道将其放置在何处,请查看此内容。
CleoR 2014年

8
Access-Control-Request-Method在请求中未设置响应。developer.mozilla.org/en-US/docs/Web/HTTP/...
kuboon

19

看一下机架式中间件。它将以可配置的方式处理CORS标头。


2
我们已经使用了几个月的机架式核心仪,到目前为止还没有发现任何问题。您确定问题不在于客户端吗?
杰夫,

1
我认为问题在于Chrome扩展程序不支持CORS,因此Origin可能为Null。如何完全禁用CORS并响应任何请求,包括起源为空的请求?
不符合规定的人

您正在使用什么Chrome扩展程序?
杰夫,

1
我正在编写一个Chrome扩展程序,该扩展程序需要与Rails后端进行通信。
不符合规定的人

12

只需添加即可添加机架式心电图宝石 https://rubygems.org/gems/rack-cors/versions/0.4.0

第一步:将gem添加到您的Gemfile中:

gem 'rack-cors', :require => 'rack/cors'

然后保存并运行 bundle install

第二步:通过添加以下内容来更新您的config / application.rb文件:

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

有关更多详细信息, 如果您不使用rails 5,则可以转到https://github.com/cyu/rack-cors


对我来说,这.insert_before 0很重要。在使用之前config.middleware.use,只有在我想允许public目录使用CORS 之前,该方法才起作用。
海啸

5

我遇到了问题,尤其是Chrome浏览器。您所做的基本上看起来像我在应用程序中所做的一样。唯一的区别是,我在Origin CORS标头中使用正确的主机名响应,而不是通配符。在我看来,Chrome对此很挑剔。

在开发和生产之间切换是很痛苦的,所以我写了这个小功能,可以在开发模式和生产模式下为我提供帮助。application_controller.rb除非另有说明,否则以下所有事情都会在我体内发生,这可能不是最佳解决方案,但是机架式起球架对我也不起作用,我不记得为什么。

def add_cors_headers
  origin = request.headers["Origin"]
  unless (not origin.nil?) and (origin == "http://localhost" or origin.starts_with? "http://localhost:")
    origin = "https://your.production-site.org"
  end
  headers['Access-Control-Allow-Origin'] = origin
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS, PUT, DELETE'
  allow_headers = request.headers["Access-Control-Request-Headers"]
  if allow_headers.nil?
    #shouldn't happen, but better be safe
    allow_headers = 'Origin, Authorization, Accept, Content-Type'
  end
  headers['Access-Control-Allow-Headers'] = allow_headers
  headers['Access-Control-Allow-Credentials'] = 'true'
  headers['Access-Control-Max-Age'] = '1728000'
end

然后我有了这个小东西,application_controller.rb因为我的网站需要登录:

before_filter :add_cors_headers
before_filter {authenticate_user! unless request.method == "OPTIONS"}

在我的身上routes.rb我也有这个东西:

match '*path', :controller => 'application', :action => 'empty', :constraints => {:method => "OPTIONS"}

这个方法看起来像这样:

def empty
  render :nothing => true
end

1
只是为了关闭圈子。仅当您从本地主机应用程序访问生产后端时,才会发生整个CORS混乱,对吧?当所有东西都投入生产时,这一切都不会发生吗?
Sebastialonso

2
仅当后端和webapp托管在同一URL下时。如果它们完全托管在两个不同的URL下,那么这也将在生产中发生。
Christoph Eicke 2014年

3

在出现网络浏览器(我的情况下为Chrome)之前,我曾遇到过类似的问题。

如果您使用的是chrome,请尝试启动它:

对于Windows:

1)在桌面上创建Chrome的快捷方式。右键单击快捷方式,然后选择“属性”,然后切换到“快捷方式”选项卡。

2)在“目标”字段中,添加以下内容:–args –disable-web-security

对于Mac,请打开终端窗口并从命令行运行此窗口:打开〜/ Applications / Google \ Chrome.app/ -args -disable-web-security

以上信息来自:

http://documentumcookbook.wordpress.com/2012/03/13/disable-cross-domain-javascript-security-in-chrome-for-development/


为什么这被否决了?我遇到的情况与问题中描述的情况类似,该问题通过在禁用网络安全性的情况下运行chrome得以解决。当您在本地运行开发服务器时,会发生此问题。显然,您不会让chrome在始终禁用网络安全的情况下运行。
PropertyWebBuilder

这不应该被否决,因为他正确地解释了这种情况:)
Dzung Nguyen 2013年

4
我没有进行否决,但是从答案来看,不清楚仅是出于发展目的的解决方案。虽然这可以在本地解决问题,但不能期望您的Web访问者/扩展用户可以这样做。因此,我将在答案中对此进行澄清。
nathanvda

1
这里也没有否决权,但过去是因为第一个带有给定标志的chrome实例运行导致所有其他实例以相同方式运行。要非常警惕的东西。忘记和做一些即兴冲浪非常容易。
dc5

2

刚在生产中的我的rails应用程序中遇到过此问题。这里的许多答案都给了我一些提示,并帮助我最终得出了对我来说很好的答案。

我正在运行Nginx,它很简单,只需修改my_app.conf文件(其中my_app是您的应用程序名称)。您可以在以下位置找到该文件/etc/nginx/conf.d

如果还没有,则location / {}可以将其添加到server {},然后在add_header 'Access-Control-Allow-Origin' '*';下方添加location / {}

最终格式应如下所示:

server {
    server_name ...;
    listen ...;
    root ...;

    location / {
        add_header 'Access-Control-Allow-Origin' '*';
    }
}

-2

尝试在/config/application.rb中进行配置:

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

您忘了提到开发人员应在Gemfile中添加“ rack-cors”
Gabriel Lidenor
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.