Cho phép mọi thứ thông qua Chính sách CORS


100

Làm cách nào để vô hiệu hóa mã? Vì lý do nào đó, tôi đã đánh dấu nguồn gốc và tiêu đề được phép nhưng các yêu cầu ajax của tôi vẫn phàn nàn rằng nguồn gốc không được chính sách CORS của tôi cho phép ....

Bộ điều khiển ứng dụng của tôi:

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

các tuyến đường:

  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"

Biên tập---

Tôi cũng đã thử:

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

trong application.rb

- chỉnh sửa 2 ---

Tôi nghĩ có vấn đề là Tiện ích mở rộng của Chrome có thể không hỗ trợ CORS. Làm cách nào để tôi có thể tìm nạp thông tin khi bỏ qua CORS? Tôi nên phản hồi như thế nào đối với việc kiểm tra trước chuyến bay?


1
Không "vô hiệu hóa CORS" nhưng hiệu quả không có chính sách? Tôi dường như không thể đáp ứng bất kỳ yêu cầu nào.
không tuân thủ

1
Bạn có sử dụng cái này trên localhost không?
Dzung Nguyen

Câu trả lời:


154

Tôi cũng yêu cầu của bạn đối với một API công khai mà tôi đã sử dụng rails-api.

Tôi cũng đã đặt tiêu đề trong bộ lọc trước. Nó trông như thế này:

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'

Có vẻ như bạn đã bỏ lỡ tiêu đề Access-Control-Request-Method.


Thật là lạ. Bạn có thể cung cấp thêm thông tin về lỗi bạn gặp phải không?
matteo

github.com/cleor41/Cors-Rails4-API Kiểm tra phần này nếu bạn không biết đặt nó ở đâu.
CleoR

8
Access-Control-Request-Method được đặt trong yêu cầu không được phản hồi. developer.mozilla.org/en-US/docs/Web/HTTP/…
kuboon

19

Hãy xem phần mềm trung gian rack-cors . Nó sẽ xử lý các tiêu đề CORS theo cách có thể định cấu hình.


2
Chúng tôi đã sử dụng rack-cors trong nhiều tháng và không phát sinh bất kỳ vấn đề nào cho đến nay. Bạn có chắc chắn sự cố không nằm ở phía máy khách?
Jef

1
Tôi nghĩ vấn đề là Tiện ích mở rộng của Chrome không hỗ trợ CORS nên có thể Nguồn gốc là Không. Làm cách nào để tôi có thể vô hiệu hóa hoàn toàn CORS và phản hồi bất kỳ yêu cầu nào kể cả các yêu cầu có nguồn gốc Null?
Nonconformist

Bạn đang sử dụng Tiện ích mở rộng Chrome nào?
Jef

1
Tôi đang viết một tiện ích mở rộng chrome cần giao tiếp với phần phụ trợ Rails của tôi.
Nonconformist

12

Đơn giản, bạn có thể thêm đá quý rack-cors https://rubygems.org/gems/rack-cors/versions/0.4.0

Bước đầu tiên: thêm đá quý vào Gemfile của bạn:

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

và sau đó lưu và chạy bundle install

Bước 2: Cập nhật tệp config / application.rb của bạn bằng cách thêm vào:

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

để biết thêm chi tiết, bạn có thể truy cập https://github.com/cyu/rack-cors Cụ thể nếu bạn không sử dụng rails 5.


Đối với tôi điều .insert_before 0quan trọng. Trước khi tôi sử dụng config.middleware.usevà điều đó chỉ hoạt động cho đến khi tôi muốn cho phép CORS cho publicthư mục của mình .
Sóng thần

5

Tôi cũng gặp sự cố, đặc biệt là với Chrome. Những gì bạn đã làm về cơ bản giống như những gì tôi đã làm trong ứng dụng của mình. Sự khác biệt duy nhất là tôi đang phản hồi với tên máy chủ chính xác trong tiêu đề Origin CORS của tôi chứ không phải ký tự đại diện. Đối với tôi, có vẻ như Chrome khá kén chọn điều này.

Chuyển đổi giữa phát triển và sản xuất là một điều khó khăn, vì vậy tôi đã viết một chức năng nhỏ này giúp tôi trong chế độ phát triển và cả chế độ sản xuất. Tất cả những điều sau đây xảy ra với tôi application_controller.rbtrừ khi có lưu ý khác, nó có thể không phải là giải pháp tốt nhất, nhưng những chiếc rack-cors cũng không hoạt động với tôi, tôi không thể nhớ tại sao.

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

Và sau đó tôi có một thứ nhỏ này trong người application_controller.rbvì trang web của tôi yêu cầu đăng nhập:

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

Trong tôi routes.rbcũng có thứ này:

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

và phương thức này trông như thế này:

def empty
  render :nothing => true
end

1
Chỉ để đóng vòng tròn. Toàn bộ mớ hỗn độn CORS này chỉ xảy ra khi bạn đánh back-end sản xuất của mình từ một ứng dụng localhost, phải không? Điều này sẽ không xảy ra khi mọi thứ đang trong quá trình sản xuất?
Sebastialonso

2
Chỉ khi chương trình phụ trợ và ứng dụng web được lưu trữ dưới cùng một URL. Nếu chúng được lưu trữ hoàn toàn dưới hai URL khác nhau, thì điều này cũng sẽ xảy ra trong quá trình sản xuất.
Christoph Eicke

3

Tôi đã gặp sự cố tương tự trước đây, trong đó hóa ra là trình duyệt web (trong trường hợp của tôi là chrome), đó là sự cố.

Nếu bạn đang sử dụng chrome, hãy thử khởi chạy nó như vậy:

Cho cửa sổ:

1) Tạo lối tắt đến Chrome trên màn hình của bạn. Nhấp chuột phải vào phím tắt và chọn Thuộc tính, sau đó chuyển sang tab “Phím tắt”.

2) Trong trường “Mục tiêu”, thêm phần sau: –args –disable-web-security

Đối với Mac, Mở cửa sổ dòng lệnh và chạy nó từ dòng lệnh: open ~ / Applications / Google \ Chrome.app/ –args –disable-web-security

Thông tin trên từ:

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


Tại sao điều này đã bị bỏ phiếu? Tôi đã gặp phải tình huống tương tự như tình huống được mô tả trong câu hỏi đã được giải quyết bằng cách chạy chrome với tính năng bảo mật web bị tắt. Sự cố xảy ra khi bạn đang chạy một máy chủ phát triển cục bộ. Rõ ràng là bạn sẽ không để chrome chạy với bảo mật web luôn bị tắt.
PropertyWebBuilder

cái này không nên bỏ phiếu vì anh ấy giải thích tình huống đúng :)
Dzung Nguyen.

4
Tôi đã không bỏ phiếu, nhưng từ câu trả lời thì không rõ đây là một giải pháp đơn thuần cho mục đích phát triển. Mặc dù điều này có thể giải quyết vấn đề cục bộ, người ta không thể mong đợi khách truy cập web / người dùng tiện ích mở rộng của bạn làm điều này. Vì vậy, tôi sẽ làm rõ điều đó trong câu trả lời.
nathanvda

1
Ở đây cũng không bỏ phiếu, nhưng trước đây, phiên bản đầu tiên của chrome chạy với một cờ nhất định đã khiến tất cả các phiên bản khác chạy theo cùng một cách. Một cái gì đó phải rất cảnh giác. Tất cả đều quá dễ dàng để quên và thực hiện một số hoạt động lướt web ngẫu hứng.
dc5

2

Chỉ gặp vấn đề này trong ứng dụng rails của tôi trong sản xuất. Rất nhiều câu trả lời ở đây đã cho tôi gợi ý và giúp tôi cuối cùng đi đến một câu trả lời phù hợp với tôi.

Tôi đang chạy Nginx và nó đủ đơn giản để chỉ cần sửa đổi tệp my_app.conf (trong đó my_app là tên ứng dụng của bạn). Bạn có thể tìm thấy tệp này trong/etc/nginx/conf.d

Nếu bạn chưa có, location / {}bạn chỉ có thể thêm nó vào dưới server {}, sau đó thêm vào add_header 'Access-Control-Allow-Origin' '*';dưới location / {}.

Định dạng cuối cùng sẽ trông giống như sau:

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

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

-2

Hãy thử cấu hình tại /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

Bạn quên đề cập đến các dev nên thêm 'rack CORS' trong Gemfile
Gabriel Lidenor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.