Permitir qualquer coisa por meio da política CORS

100

Como posso desativar cors? Por algum motivo, alterei as origens e cabeçalhos permitidos, mas minhas solicitações de ajax ainda reclamam que a origem não foi permitida pela minha política CORS ....

Meu controlador de aplicativos:

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

rotas:

  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---

Eu também tentei:

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

em application.rb

--editar 2 ---

O problema é que as extensões do Chrome podem não suportar CORS, eu acho. Como posso obter informações ignorando o CORS? Como devo responder à verificação do preflight?

Dissidente
fonte
1
Não "desabilitar CORS" mas efetivamente não tem política? Não consigo responder a nenhum pedido.
Não
1
Você usa isso no localhost?
Dzung Nguyen

Respostas:

154

Eu tenho os mesmos requisitos em uma API pública para a qual usei rails-api.

Também defini o cabeçalho em um filtro anterior. Se parece com isso:

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 você perdeu o cabeçalho Access-Control-Request-Method.

matteo
fonte
Isso é estranho. Você poderia fornecer mais informações sobre o erro que obteve?
matteo
github.com/cleor41/Cors-Rails4-API Verifique se você não sabe onde colocá-lo ainda.
CleoR
8
Access-Control-Request-Method é definido na solicitação, não na resposta. developer.mozilla.org/en-US/docs/Web/HTTP/…
kuboon
19

Dê uma olhada no middleware rack-cors . Ele tratará os cabeçalhos CORS de uma maneira configurável.

Jef
fonte
2
Nós usamos rack-cors por meses e não encontramos nenhum problema até agora. Tem certeza de que o problema não reside no lado do cliente?
Jef
1
Acho que o problema é que as extensões do Chrome não suportam CORS, então talvez a origem seja nula. Como posso desabilitar completamente o CORS e responder a qualquer solicitação, incluindo solicitações com origens nulas?
Não
Qual extensão do Chrome você está usando?
Jef
1
Estou escrevendo uma extensão do Chrome que precisa se comunicar com meu back-end do Rails.
Não
12

Simplesmente você pode adicionar rack-cors gem https://rubygems.org/gems/rack-cors/versions/0.4.0

1ª Etapa: adicionar gema ao seu Gemfile:

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

e então salvar e executar bundle install

2ª etapa: atualize seu arquivo config / application.rb adicionando este:

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

para mais detalhes você pode ir para https://github.com/cyu/rack-cors Specailly se você não usa rails 5.

Abdallah Okasha
fonte
Para mim, o .insert_before 0foi importante. Antes eu usava config.middleware.usee funcionava apenas até eu querer permitir CORS para meu publicdiretório.
Tsunamis
5

Eu tive problemas, especialmente com o Chrome também. O que você fez parece essencialmente com o que fiz em meu aplicativo. A única diferença é que estou respondendo com nomes de host corretos nos cabeçalhos do Origin CORS e não com um caractere curinga. Parece-me que o Chrome é exigente com isso.

Alternar entre desenvolvimento e produção é uma dor, então escrevi esta pequena função que me ajuda no modo de desenvolvimento e também no modo de produção. Todas as coisas a seguir acontecem no meu, a application_controller.rbmenos que indicado de outra forma, pode não ser a melhor solução, mas rack-cors não funcionou para mim também, não consigo me lembrar 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

E então eu tenho uma pequena coisa no meu application_controller.rbporque meu site requer um login:

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

No meu routes.rbtambém tenho essa coisa:

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

e este método se parece com este:

def empty
  render :nothing => true
end
Christoph Eicke
fonte
1
Só para fechar o círculo. Toda essa bagunça do CORS só acontece quando você acessa o back-end de produção de um aplicativo localhost, certo? Nada disso vai acontecer quando tudo estiver em produção?
Sebastialonso
2
Somente se o back-end e o webapp estiverem hospedados no mesmo URL. Se eles estiverem hospedados em dois URLs diferentes, isso também acontecerá na produção.
Christoph Eicke de
3

Eu tive um problema semelhante antes em que acabou sendo o navegador da web (cromo no meu caso) que era o problema.

Se você estiver usando o Chrome, tente iniciá-lo para:

Para Windows:

1) Crie um atalho para o Chrome em sua área de trabalho. Clique com o botão direito do mouse no atalho e escolha Propriedades, a seguir mude para a guia “Atalho”.

2) No campo “Destino”, acrescente o seguinte: –args –disable-web-security

Para Mac, abra uma janela de terminal e execute-a na linha de comando: open ~ / Applications / Google \ Chrome.app/ –args –disable-web-security

Informações acima de:

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

PropertyWebBuilder
fonte
Por que isso foi rejeitado? Eu tive uma situação semelhante à descrita na pergunta que foi resolvida executando o Chrome com a segurança da web desativada. O problema ocorre quando você está executando um servidor de desenvolvimento localmente. Obviamente, você não deixaria o Chrome em execução com a segurança da Web sempre desativada.
PropertyWebBuilder
isso não deve ser rejeitado, pois ele explica a situação corretamente :)
Dzung Nguyen
4
Não votei contra, mas da resposta não fica claro que esta seja uma solução meramente para fins de desenvolvimento. Embora isso possa resolver o problema localmente, não se pode esperar que os visitantes da web / usuários de extensão façam isso. Portanto, gostaria de esclarecer isso na resposta.
nathanvda
1
Sem votação aqui também, mas costumava ser que a primeira instância do Chrome executado com um determinado sinalizador fazia com que todas as outras instâncias fossem executadas da mesma maneira. Algo para se ter muito cuidado. É muito fácil esquecer e fazer surfe improvisado.
DC5
2

Acabei de encontrar esse problema em meu aplicativo Rails em produção. Muitas respostas aqui me deram dicas e me ajudaram a finalmente chegar a uma resposta que funcionou bem para mim.

Estou executando o Nginx e foi simples o suficiente apenas modificar o arquivo my_app.conf (onde my_app é o nome do seu aplicativo). Você pode encontrar este arquivo em/etc/nginx/conf.d

Se ainda não o fez, location / {}pode apenas adicioná-lo em e server {}, em seguida, adicionar add_header 'Access-Control-Allow-Origin' '*';emlocation / {} .

O formato final deve ser semelhante a este:

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

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

Tente a configuração em /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 Ostan
fonte
Você se esqueceu de mencionar que o desenvolvedor deve adicionar 'rack-cors' no Gemfile
Gabriel Lidenor