Permitir cualquier cosa a través de la política CORS

100

¿Cómo puedo desactivar cors? Por alguna razón, modifiqué los orígenes y encabezados permitidos, pero mis solicitudes de ajax todavía se quejan de que mi política CORS no permitía el origen ...

Mi controlador de aplicaciones:

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

rutas:

  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"

Editar---

También probé:

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

en application.rb

--editar 2 ---

El problema es que las extensiones de Chrome pueden no ser compatibles con CORS, creo. ¿Cómo puedo obtener información sin pasar por CORS? ¿Cómo debo responder a la verificación previa al vuelo?

Inconformista
fuente
1
¿No "deshabilita CORS" pero efectivamente no tiene política? Parece que no puedo responder a ninguna solicitud.
Inconformista
1
¿Usas esto en localhost?
Dzung Nguyen

Respuestas:

154

Tengo sus mismos requisitos en una API pública para la que usé rails-api.

También configuré el encabezado en un filtro anterior. Se parece a esto:

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'

Parece que se perdió el encabezado Access-Control-Request-Method.

matteo
fuente
Eso es extraño. ¿Podría proporcionar más información sobre el error que recibe?
matteo
github.com/cleor41/Cors-Rails4-API Mira esto si no sabes dónde ponerlo.
CleoR
8
Access-Control-Request-Method se establece en la solicitud, no en la respuesta. developer.mozilla.org/en-US/docs/Web/HTTP/…
kuboon
19

Eche un vistazo al middleware rack-cors . Manejará los encabezados CORS de una manera configurable.

Jef
fuente
2
Hemos utilizado rack-cors durante meses y hasta ahora no hemos detectado ningún problema. ¿Está seguro de que el problema no reside en el lado del cliente?
Jef
1
Creo que el problema es que las extensiones de Chrome no son compatibles con CORS, por lo que quizás el origen sea nulo. ¿Cómo puedo deshabilitar completamente CORS y responder a cualquier solicitud, incluidas las solicitudes con orígenes nulos?
Inconformista
¿Qué extensión de Chrome estás usando?
Jef
1
Estoy escribiendo una extensión de Chrome que necesita comunicarse con mi backend de Rails.
No conformista
12

Simplemente puede agregar la gema rack-cors https://rubygems.org/gems/rack-cors/versions/0.4.0

Primer paso: agregue gema a su Gemfile:

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

y luego guardar y ejecutar bundle install

2do paso: actualice su archivo config / application.rb agregando esto:

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

para obtener más detalles, puede ir a https://github.com/cyu/rack-cors Specailly si no usa rieles 5.

Abdallah Okasha
fuente
Para mí .insert_before 0fue importante. Antes lo usaba config.middleware.usey eso funcionó solo hasta que quise permitir CORS para mi publicdirectorio.
Tsunamis
5

Tuve problemas, especialmente con Chrome también. Lo que hiciste se parece esencialmente a lo que hice en mi solicitud. La única diferencia es que estoy respondiendo con un nombre de host correcto en mis encabezados CORS de Origin y no con un comodín. Me parece que Chrome es quisquilloso con esto.

Cambiar entre desarrollo y producción es una molestia, así que escribí esta pequeña función que me ayuda en el modo de desarrollo y también en el modo de producción. Todas las siguientes cosas suceden en mi, a application_controller.rbmenos que se indique lo contrario, puede que no sea la mejor solución, pero los rack-cors tampoco funcionaron para mí, no recuerdo por qué.

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

Y luego tengo esta pequeña cosa en mi application_controller.rbporque mi sitio requiere un inicio de sesión:

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

En mi routes.rbtambién tengo esta cosa:

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

y este método se ve así:

def empty
  render :nothing => true
end
Christoph Eicke
fuente
1
Solo para cerrar el círculo. Todo este lío de CORS solo ocurre cuando accedes a tu back-end de producción desde una aplicación de host local, ¿verdad? ¿Nada de esto sucederá cuando todo esté en producción?
Sebastialonso
2
Solo si el backend y la aplicación web están alojados en la misma URL. Si están alojados en dos URL diferentes por completo, esto también sucederá en producción.
Christoph Eicke
3

He tenido un problema similar antes en el que resultó ser el navegador web (Chrome en mi caso) el problema.

Si está utilizando Chrome, intente iniciarlo así:

Para ventanas:

1) Cree un acceso directo a Chrome en su escritorio. Haga clic derecho en el acceso directo y seleccione Propiedades, luego cambie a la pestaña "Acceso directo".

2) En el campo "Destino", agregue lo siguiente: –args –disable-web-security

Para Mac, abra una ventana de terminal y ejecute esto desde la línea de comandos: abra ~ / Applications / Google \ Chrome.app/ –args –disable-web-security

Información anterior de:

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

PropertyWebBuilder
fuente
¿Por qué se ha rechazado esto? Tuve una situación similar a la descrita en la pregunta que se resolvió ejecutando Chrome con la seguridad web desactivada. El problema ocurre cuando está ejecutando un servidor de desarrollo localmente. Obviamente, no dejaría Chrome funcionando con la seguridad web desactivada siempre.
PropertyWebBuilder
esto no debería rechazarse, ya que explica la situación correctamente :)
Dzung Nguyen
4
No hice la votación en contra, pero de la respuesta no está claro que se trate de una solución meramente con fines de desarrollo. Si bien esto podría resolver el problema localmente, no se puede esperar que sus visitantes web / usuarios de extensiones hagan esto. Así que aclararía eso en la respuesta.
nathanvda
1
Aquí tampoco hay voto negativo, pero solía ser que la primera instancia de Chrome ejecutada con una bandera determinada hacía que todas las demás instancias se ejecutaran de la misma manera. Algo de lo que tener mucho cuidado. Es muy fácil de olvidar y hacer un poco de surf improvisado.
dc5
2

Acabo de encontrar este problema en mi aplicación de rieles en producción. Muchas de las respuestas aquí me dieron pistas y me ayudaron a finalmente llegar a una respuesta que funcionó bien para mí.

Estoy ejecutando Nginx y fue lo suficientemente simple como para modificar el archivo my_app.conf (donde my_app es el nombre de su aplicación). Puede encontrar este archivo en/etc/nginx/conf.d

Si aún no lo ha location / {}hecho, puede agregarlo debajo server {}y luego agregar add_header 'Access-Control-Allow-Origin' '*';debajo location / {}.

El formato final debería verse así:

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

    location / {
        add_header 'Access-Control-Allow-Origin' '*';
    }
}
media pensión
fuente
-2

Pruebe la configuración en /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
Leonardo Ostán
fuente
Olvidó mencionar que el desarrollador debería agregar los 'rack-cors' en el Gemfile
Gabriel Lidenor