Consenti qualsiasi cosa tramite la policy CORS


100

Come posso disabilitare cors? Per qualche motivo ho inserito con il jolly le origini e le intestazioni consentite, ma le mie richieste ajax continuano a lamentarsi del fatto che l'origine non era consentita dalla mia politica CORS ....

Controller delle mie applicazioni:

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

itinerari:

  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"

Modificare---

Ho anche provato:

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

in application.rb

- modifica 2 ---

Il problema è che le estensioni di Chrome potrebbero non supportare CORS, credo. Come posso recuperare le informazioni bypassando CORS? Come devo rispondere al controllo preliminare?


1
Non "disabilita CORS" ma effettivamente non hai criteri? Non riesco a rispondere a nessuna richiesta.
Anticonformista

1
Lo usi su localhost?
Dzung Nguyen

Risposte:


154

Ho i tuoi stessi requisiti su un'API pubblica per la quale ho usato rails-api.

Ho anche impostato l'intestazione in un filtro prima. Assomiglia a questo:

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'

Sembra che tu abbia perso l'intestazione Access-Control-Request-Method.


È strano. Potresti fornire maggiori informazioni sull'errore che ricevi?
matteo

github.com/cleor41/Cors-Rails4-API Controlla questo se non sai dove metterlo ancora.
CleoR

8
Access-Control-Request-Method è impostato nella richiesta non in risposta. developer.mozilla.org/en-US/docs/Web/HTTP/…
kuboon

19

Dai un'occhiata al middleware rack-cors . Gestirà le intestazioni CORS in modo configurabile.


2
Abbiamo utilizzato rack-cors per mesi e finora non abbiamo riscontrato alcun problema. Sei sicuro che il problema non risieda sul lato client?
Jef

1
Penso che il problema sia che le estensioni di Chrome non supportano CORS, quindi forse l'origine è nulla. Come posso disabilitare completamente CORS e rispondere a qualsiasi richiesta comprese le richieste con origini Null?
Anticonformista

Quale estensione di Chrome stai utilizzando?
Jef

1
Sto scrivendo un'estensione per Chrome che deve comunicare con il mio backend Rails.
Anticonformista

12

Semplicemente puoi aggiungere gemma rack-cors https://rubygems.org/gems/rack-cors/versions/0.4.0

1 ° passaggio: aggiungi gemma al tuo Gemfile:

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

e poi salva ed esegui bundle install

2 ° passaggio: aggiorna il tuo file config / application.rb aggiungendo questo:

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

per maggiori dettagli puoi andare su https://github.com/cyu/rack-cors Specailly se non usi rails 5.


Per me .insert_before 0era importante. Prima lo usavo config.middleware.usee funzionava solo fino a quando non volevo consentire CORS per la mia publicdirectory.
Tsunami il

5

Ho avuto problemi, soprattutto con Chrome. Quello che hai fatto sembra essenzialmente quello che ho fatto nella mia applicazione. L'unica differenza è che rispondo con un nome host corretto nelle intestazioni CORS di Origin e non con un carattere jolly. Mi sembra che Chrome sia pignolo con questo.

Passare dallo sviluppo alla produzione è una seccatura, quindi ho scritto questa piccola funzione che mi aiuta in modalità di sviluppo e anche in modalità di produzione. Tutte le seguenti cose accadono nel mio application_controller.rbse non diversamente specificato, potrebbe non essere la soluzione migliore, ma nemmeno il rack-cors ha funzionato per me, non ricordo perché.

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

E poi ho questa piccola cosa nel mio application_controller.rbperché il mio sito richiede un login:

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

Nel mio routes.rbho anche questa cosa:

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

e questo metodo è simile a questo:

def empty
  render :nothing => true
end

1
Giusto per chiudere il cerchio. L'intero pasticcio CORS si verifica solo quando raggiungi il back-end di produzione da un'applicazione localhost, giusto? Niente di tutto questo accadrà quando tutto sarà in produzione?
Sebastialonso

2
Solo se backend e webapp sono ospitati sotto lo stesso URL. Se sono ospitati interamente sotto due URL diversi, ciò avverrà anche in produzione.
Christoph Eicke

3

Ho avuto un problema simile prima dove si è scoperto che era il browser web (chrome nel mio caso) che era il problema.

Se stai usando Chrome, prova ad avviarlo così:

Per Windows:

1) Crea un collegamento a Chrome sul desktop. Fare clic con il tasto destro sul collegamento e scegliere Proprietà, quindi passare alla scheda "Collegamento".

2) Nel campo "Target", aggiungere quanto segue: –args –disable-web-security

Per Mac, apri una finestra di terminale ed eseguilo dalla riga di comando: apri ~ / Applications / Google \ Chrome.app/ –args –disable-web-security

Informazioni sopra da:

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


Perché è stato bocciato? Ho avuto una situazione simile a quella descritta nella domanda che è stata risolta eseguendo Chrome con la sicurezza web disabilitata. Il problema si verifica quando si esegue localmente un server di sviluppo. Ovviamente non lasceresti Chrome in esecuzione con la sicurezza web disabilitata sempre.
PropertyWebBuilder

questo non dovrebbe essere respinto poiché spiega correttamente la situazione :)
Dzung Nguyen

4
Non ho votato a favore, ma dalla risposta non è chiaro che si tratti di una soluzione meramente a fini di sviluppo. Anche se questo potrebbe risolvere il problema localmente, non ci si può aspettare che i tuoi visitatori web / utenti di estensioni lo facciano. Quindi vorrei chiarirlo nella risposta.
nathanvda

1
Anche qui non si vota, ma in passato la prima istanza di chrome eseguita con un determinato flag faceva sì che tutte le altre istanze funzionassero allo stesso modo. Qualcosa di essere molto cauti. È fin troppo facile dimenticare e fare surf improvvisato.
cc5

2

Ho appena riscontrato questo problema nella mia applicazione rails in produzione. Molte risposte qui mi hanno dato suggerimenti e mi hanno aiutato a trovare finalmente una risposta che funzionasse bene per me.

Sto eseguendo Nginx ed è stato abbastanza semplice modificare il file my_app.conf (dove my_app è il nome dell'app). Puoi trovare questo file in/etc/nginx/conf.d

Se non lo hai location / {}già, puoi semplicemente aggiungerlo sotto server {}, quindi aggiungere add_header 'Access-Control-Allow-Origin' '*';sotto location / {}.

Il formato finale dovrebbe essere simile a questo:

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

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

-2

Prova la configurazione su /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

Hai dimenticato di menzionare che lo sviluppatore dovrebbe aggiungere il 'rack-cors' nel Gemfile
Gabriel Lidenor
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.