111 votes

Autoriser tout par la politique CORS

Comment puis-je désactiver les cors ? Pour une raison ou une autre, j'ai modifié les origines et les en-têtes autorisés, mais mes requêtes ajax se plaignent toujours que l'origine n'est pas autorisée par ma politique CORS.....

Mon contrôleur d'applications :

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

routes :

  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"

Edit---

J'ai aussi essayé :

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

dans application.rb

--edit 2---

Le problème est que les extensions de Chrome ne prennent pas en charge CORS, je pense. Comment puis-je récupérer des informations en contournant CORS ? Comment dois-je répondre à la vérification préalable ?

162voto

matteo Points 706

J'ai les mêmes exigences pour une API publique pour laquelle j'ai utilisé rails-api.

J'ai également placé l'en-tête dans un filtre avant. Cela ressemble à ceci :

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'

Il semble que vous ayez manqué l'en-tête Access-Control-Request-Method.

22voto

Jef Points 3486

Jetez un coup d'œil à la rack-cors intergiciel. Il traitera les en-têtes CORS de manière configurable.

17voto

Abdallah Okasha Points 442

Vous pouvez tout simplement ajouter des gemmes à crémaillère https://rubygems.org/gems/rack-cors/versions/0.4.0

1ère étape : ajouter gem à votre Gemfile :

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

puis enregistrez et exécutez bundle install

2ème étape : mettez à jour votre fichier config/application.rb en ajoutant ceci :

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

Pour plus de détails, vous pouvez consulter le site https://github.com/cyu/rack-cors Surtout si vous n'utilisez pas les rails 5.

6voto

Christoph Eicke Points 739

J'ai eu des problèmes, surtout avec Chrome également. Ce que vous avez fait ressemble essentiellement à ce que j'ai fait dans mon application. La seule différence est que je réponds avec un nom d'hôte correct dans mes en-têtes CORS d'origine et non avec un caractère générique. Il me semble que Chrome est pointilleux à ce sujet.

Le passage entre le développement et la production est un problème, j'ai donc écrit cette petite fonction qui m'aide en mode développement et aussi en mode production. Toutes les choses suivantes se produisent dans mon application_controller.rb sauf indication contraire, il se peut que ce ne soit pas la meilleure solution, mais rack-cors n'a pas marché pour moi non plus, je ne me souviens plus pourquoi.

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

Et puis j'ai cette petite chose dans mon application_controller.rb parce que mon site nécessite une connexion :

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

Dans mon routes.rb J'ai aussi ce truc :

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

et cette méthode ressemble à ceci :

def empty
  render :nothing => true
end

4voto

deepinder Points 56

Utiliser la gemme rack-cors. Cela résout le problème des domaines croisés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X