Lassen Sie alles über die CORS-Richtlinie zu


100

Wie kann ich cors deaktivieren? Aus irgendeinem Grund habe ich die zulässigen Ursprünge und Überschriften mit einem Wildcard versehen, aber meine Ajax-Anfragen beschweren sich immer noch, dass der Ursprung nach meiner CORS-Richtlinie nicht zulässig war.

Mein Anwendungscontroller:

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

Routen:

  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"

Bearbeiten---

Ich habe auch versucht:

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

in application.rb

--edit 2 ---

Das Problem ist, dass Chrome Extensions CORS möglicherweise nicht unterstützen, denke ich. Wie kann ich Informationen unter Umgehung von CORS abrufen? Wie soll ich auf den Preflight-Check reagieren?


1
Nicht "CORS deaktivieren", aber effektiv keine Richtlinie haben? Ich kann auf keine Anfrage antworten.
Nonkonformist

1
Verwenden Sie dies auf localhost?
Dzung Nguyen

Antworten:


154

Ich habe dieselben Anforderungen an eine öffentliche API, für die ich Rails-API verwendet habe.

Ich habe auch den Header in einem Vorfilter gesetzt. Es sieht aus wie das:

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'

Anscheinend haben Sie den Header Access-Control-Request-Method verpasst.


Das ist seltsam. Könnten Sie weitere Informationen zu dem Fehler geben, den Sie erhalten?
Matto

github.com/cleor41/Cors-Rails4-API Überprüfen Sie dies, wenn Sie nicht wissen, wo Sie es noch ablegen sollen .
CleoR

8
Die Zugriffssteuerungs-Anforderungsmethode wird in der Anforderung nicht als Antwort festgelegt. developer.mozilla.org/en-US/docs/Web/HTTP/…
Kuboon

19

Schauen Sie sich die Rack-Cors- Middleware an. CORS-Header werden konfigurierbar behandelt.


2
Wir haben monatelang Rack-Cors verwendet und sind bisher auf kein Problem gestoßen. Sind Sie sicher, dass das Problem nicht auf der Clientseite liegt?
Jef

1
Ich denke, das Problem ist, dass Chrome Extensions CORS nicht unterstützen. Vielleicht ist der Ursprung Null. Wie kann ich CORS vollständig deaktivieren und auf Anfragen antworten, einschließlich Anfragen mit Null-Ursprung?
Nonkonformist

Welche Chrome-Erweiterung verwenden Sie?
Jef

1
Ich schreibe eine Chrome-Erweiterung, die mit meinem Rails-Backend kommunizieren muss.
Nonkonformist

12

Sie können einfach das Rack-Cors-Juwel https://rubygems.org/gems/rack-cors/versions/0.4.0 hinzufügen

1. Schritt: Fügen Sie Ihrem Gemfile einen Edelstein hinzu:

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

und dann speichern und ausführen bundle install

2. Schritt: Aktualisieren Sie Ihre Datei config / application.rb, indem Sie Folgendes hinzufügen:

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

Weitere Informationen finden Sie unter https://github.com/cyu/rack-cors. Insbesondere, wenn Sie keine Schienen verwenden. 5.


Für mich .insert_before 0war das wichtig. Vorher habe ich verwendet config.middleware.useund das hat nur funktioniert, bis ich CORS für mein publicVerzeichnis zulassen wollte .
Tsunamis

5

Ich hatte Probleme, insbesondere auch mit Chrome. Was Sie getan haben, sieht im Wesentlichen so aus, wie ich es in meiner Bewerbung getan habe. Der einzige Unterschied besteht darin, dass ich in meinen Origin CORS-Headern mit einem korrekten Hostnamen und nicht mit einem Platzhalter antworte. Es scheint mir, dass Chrome damit wählerisch ist.

Das Umschalten zwischen Entwicklung und Produktion ist ein Schmerz, deshalb habe ich diese kleine Funktion geschrieben, die mir im Entwicklungsmodus und auch im Produktionsmodus hilft. Alle folgenden Dinge passieren in meinem, application_controller.rbwenn nicht anders angegeben, es ist vielleicht nicht die beste Lösung, aber Rack-Cors haben auch bei mir nicht funktioniert, ich kann mich nicht erinnern warum.

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

Und dann habe ich dieses kleine Ding in meinem, application_controller.rbweil meine Seite ein Login erfordert:

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

In meinem habe routes.rbich auch dieses Ding:

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

und diese Methode sieht so aus:

def empty
  render :nothing => true
end

1
Nur um den Kreis zu schließen. Dieses ganze CORS-Durcheinander passiert nur, wenn Sie Ihr Produktions-Backend von einer Localhost-Anwendung aus erreichen, oder? Nichts davon wird passieren, wenn alles in Produktion ist?
Sebastialonso

2
Nur wenn Backend und Webapp unter derselben URL gehostet werden. Wenn sie vollständig unter zwei verschiedenen URLs gehostet werden, geschieht dies auch in der Produktion.
Christoph Eicke

3

Ich hatte zuvor ein ähnliches Problem, bei dem sich herausstellte, dass der Webbrowser (in meinem Fall Chrom) das Problem war.

Wenn Sie Chrome verwenden, starten Sie es wie folgt:

Für Windows:

1) Erstellen Sie eine Verknüpfung zu Chrome auf Ihrem Desktop. Klicken Sie mit der rechten Maustaste auf die Verknüpfung, wählen Sie Eigenschaften und wechseln Sie dann zur Registerkarte "Verknüpfung".

2) Fügen Sie im Feld "Ziel" Folgendes hinzu: –args –disable-web-security

Öffnen Sie für Mac ein Terminalfenster und führen Sie dieses über die Befehlszeile aus: Öffnen Sie ~ / Applications / Google \ Chrome.app/ –args –disable-web-security

Oben Infos von:

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


Warum wurde dies abgelehnt? Ich hatte eine ähnliche Situation wie in der Frage beschrieben, die durch Ausführen von Chrome mit deaktivierter Websicherheit behoben wurde. Das Problem tritt auf, wenn Sie einen Entwicklungsserver lokal ausführen. Natürlich würden Sie Chrome nicht immer mit deaktivierter Web-Sicherheit laufen lassen.
PropertyWebBuilder

Dies sollte nicht
abgelehnt

4
Ich habe nicht abgestimmt, aber aus der Antwort geht nicht hervor, dass dies eine Lösung nur für Entwicklungszwecke ist. Während dies das Problem lokal lösen könnte, kann man nicht erwarten, dass Ihre Webbesucher / Erweiterungsbenutzer dies tun. Also würde ich das in der Antwort klarstellen.
Nathanvda

1
Auch hier gab es keine Abstimmung, aber früher führte die erste Instanz von Chrome Run mit einem bestimmten Flag dazu, dass alle anderen Instanzen auf die gleiche Weise ausgeführt wurden. Etwas, vor dem man sehr vorsichtig sein sollte. Es ist allzu leicht zu vergessen und spontan zu surfen.
DC5

2

Ich bin gerade auf dieses Problem in meiner Schienenanwendung in der Produktion gestoßen. Viele Antworten hier gaben mir Hinweise und halfen mir, endlich zu einer Antwort zu kommen, die für mich gut funktionierte.

Ich arbeite mit Nginx und es war einfach genug, nur die ändern my_app.conf Datei (wo my_app Ihr App - Name ist). Sie finden diese Datei in/etc/nginx/conf.d

Wenn Sie es noch nicht getan haben location / {}, können Sie es einfach unter hinzufügen server {}und dann add_header 'Access-Control-Allow-Origin' '*';unter hinzufügen location / {}.

Das endgültige Format sollte ungefähr so ​​aussehen:

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

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

-2

Versuchen Sie die Konfiguration unter /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

Sie haben vergessen zu erwähnen, dass der Entwickler die 'Rack-Cors' in der Gemfile hinzufügen sollte
Gabriel Lidenor
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.