Izinkan apa pun melalui Kebijakan CORS

100

Bagaimana cara menonaktifkan kors? Untuk beberapa alasan saya mengartikan asal-usul dan header yang diizinkan namun permintaan ajax saya masih mengeluh bahwa asal tidak diizinkan oleh kebijakan CORS saya ....

Pengontrol aplikasi saya:

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

rute:

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

Saya juga mencoba:

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

di application.rb

--edit 2 ---

Masalahnya adalah Ekstensi Chrome mungkin tidak mendukung CORS menurut saya. Bagaimana cara mengambil informasi dengan melewati CORS? Bagaimana saya harus menanggapi cek preflight?

Nonkonformis
sumber
1
Bukan "nonaktifkan CORS" tetapi secara efektif tidak memiliki kebijakan? Sepertinya saya tidak bisa menanggapi permintaan apa pun.
Nonkonformis
1
Apakah Anda menggunakan ini di localhost?
Dzung Nguyen

Jawaban:

154

Saya memiliki persyaratan yang sama untuk API publik yang saya gunakan rails-api.

Saya juga menyetel header di filter sebelumnya. Ini terlihat seperti ini:

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'

Sepertinya Anda melewatkan header Access-Control-Request-Method.

matteo
sumber
Itu aneh. Bisakah Anda memberikan info lebih lanjut tentang kesalahan yang Anda dapatkan?
matteo
github.com/cleor41/Cors-Rails4-API Lihat ini jika Anda tidak tahu harus meletakkannya di mana.
CleoR
8
Access-Control-Request-Method diatur dalam permintaan, bukan sebagai tanggapan. developer.mozilla.org/en-US/docs/Web/HTTP/…
kuboon
19

Lihat middleware rack-cors . Ini akan menangani header CORS dengan cara yang dapat dikonfigurasi.

Jef
sumber
2
Kami telah menggunakan rack-cors selama berbulan-bulan dan sejauh ini tidak menimbulkan masalah apa pun. Apakah Anda yakin masalahnya tidak ada di sisi klien?
Jef
1
Saya pikir masalahnya adalah Ekstensi Chrome tidak mendukung CORS jadi mungkin Origin adalah Null. Bagaimana saya bisa sepenuhnya menonaktifkan CORS dan menanggapi permintaan apa pun termasuk permintaan dengan asal Null?
Nonkonformis
Ekstensi Chrome apa yang Anda gunakan?
Jef
1
Saya menulis ekstensi chrome yang perlu berkomunikasi dengan backend Rails saya.
Nonkonformis
12

Cukup Anda dapat menambahkan permata rack-cors https://rubygems.org/gems/rack-cors/versions/0.4.0

Langkah 1: tambahkan permata ke Gemfile Anda:

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

lalu simpan dan jalankan bundle install

Langkah ke-2: perbarui file config / application.rb Anda dengan menambahkan ini:

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

untuk lebih jelasnya Anda dapat pergi ke https://github.com/cyu/rack-cors Specailly jika Anda tidak menggunakan rel 5.

Abdallah Okasha
sumber
Bagi saya .insert_before 0itu penting. Sebelum saya menggunakan config.middleware.usedan itu hanya berfungsi sampai saya ingin mengizinkan CORS untuk publicdirektori saya .
Tsunami
5

Saya mengalami masalah, terutama dengan Chrome juga. Apa yang Anda lakukan pada dasarnya terlihat seperti apa yang saya lakukan di aplikasi saya. Satu-satunya perbedaan adalah saya merespons dengan nama host yang benar di header Origin CORS saya dan bukan wildcard. Menurut saya, Chrome pilih-pilih dengan ini.

Beralih antara pengembangan dan produksi sangat merepotkan, jadi saya menulis fungsi kecil ini yang membantu saya dalam mode pengembangan dan juga dalam mode produksi. Semua hal berikut terjadi dalam diri saya application_controller.rbkecuali jika dinyatakan lain, ini mungkin bukan solusi terbaik, tetapi pemeras juga tidak berhasil untuk saya, saya tidak dapat mengingat alasannya.

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

Dan kemudian saya memiliki hal kecil ini application_controller.rbkarena situs saya membutuhkan login:

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

Di saya, routes.rbsaya juga memiliki hal ini:

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

dan metode ini terlihat seperti ini:

def empty
  render :nothing => true
end
Christoph Eicke
sumber
1
Hanya untuk menutup lingkaran. Seluruh kekacauan CORS ini hanya terjadi ketika Anda mencapai back-end produksi Anda dari aplikasi localhost, bukan? Tak satu pun dari ini akan terjadi ketika semuanya dalam produksi?
Sebastialonso
2
Hanya jika backend dan aplikasi web dihosting di bawah URL yang sama. Jika mereka dihosting di bawah dua URL yang sama sekali, maka ini akan terjadi dalam produksi juga.
Christoph Eicke
3

Saya pernah mengalami masalah serupa sebelumnya di mana ternyata browser web (dalam kasus saya chrome) itulah masalahnya.

Jika Anda menggunakan chrome, coba luncurkan begitu:

Untuk Windows:

1) Buat pintasan ke Chrome di desktop Anda. Klik kanan pada pintasan dan pilih Properti, lalu alihkan ke tab "Pintasan".

2) Di kolom "Target", tambahkan baris berikut: –args –disable-web-security

Untuk Mac, Buka jendela terminal dan jalankan dari baris perintah: open ~ / Applications / Google \ Chrome.app/ –args –disable-web-security

Info di atas dari:

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

PropertyWebBuilder
sumber
Mengapa ini ditolak? Saya pernah mengalami situasi yang mirip dengan yang dijelaskan dalam pertanyaan yang diselesaikan dengan menjalankan chrome dengan keamanan web dinonaktifkan. Masalah terjadi saat Anda menjalankan server pengembangan secara lokal. Jelas Anda tidak akan membiarkan chrome berjalan dengan keamanan web selalu dinonaktifkan.
PropertyWebBuilder
ini tidak boleh ditolak karena dia menjelaskan situasinya dengan benar :)
Dzung Nguyen
4
Saya tidak melakukan voting, tapi dari jawabannya tidak jelas ini solusi semata untuk tujuan pembangunan. Meskipun ini mungkin menyelesaikan masalah secara lokal, orang tidak dapat mengharapkan pengunjung web / pengguna ekstensi Anda melakukan ini. Jadi saya akan menjelaskannya dalam jawaban.
nathanvda
1
Tidak ada suara yang ditolak di sini juga, tetapi sebelumnya Chrome yang dijalankan dengan bendera tertentu menyebabkan semua instance lainnya berjalan dengan cara yang sama. Sesuatu yang harus sangat diwaspadai. Terlalu mudah untuk melupakan dan melakukan beberapa penjelajahan dadakan.
dc5
2

Baru saja mengalami masalah ini di aplikasi rel saya dalam produksi. Banyak jawaban di sini memberi saya petunjuk dan membantu saya akhirnya sampai pada jawaban yang berhasil bagi saya.

Saya menjalankan Nginx dan itu cukup sederhana untuk hanya memodifikasi file my_app.conf (di mana my_app adalah nama aplikasi Anda). Anda dapat menemukan file ini di/etc/nginx/conf.d

Jika Anda belum memilikinya location / {}Anda bisa menambahkannya di bawah server {}, lalu tambahkan di add_header 'Access-Control-Allow-Origin' '*';bawah location / {}.

Format akhir akan terlihat seperti ini:

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

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

Coba konfigurasi di /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
sumber
Anda lupa menyebutkan dev harus menambahkan 'rack-cors' di Gemfile
Gabriel Lidenor