อนุญาตทุกอย่างผ่านนโยบาย CORS


102

ฉันจะปิดการใช้งาน cors ได้อย่างไร? ด้วยเหตุผลบางอย่างฉันใช้ต้นกำเนิดและส่วนหัวที่อนุญาต แต่คำขอ ajax ของฉันยังคงบ่นว่าต้นกำเนิดไม่ได้รับอนุญาตตามนโยบาย CORS ของฉัน ....

ตัวควบคุมแอปพลิเคชันของฉัน:

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

เส้นทาง:

  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"

แก้ไข ---

ฉันยังลอง:

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

ใน application.rb

- แก้ไข 2 -

ปัญหาคือส่วนขยายของ Chrome อาจไม่รองรับ CORS ที่ฉันคิด ฉันจะดึงข้อมูลข้าม CORS ได้อย่างไร ฉันควรตอบสนองต่อการตรวจสอบไฟล่วงหน้าอย่างไร


1
ไม่ "ปิดการใช้งาน CORS" แต่ไม่มีนโยบายอย่างมีประสิทธิภาพ? ดูเหมือนฉันจะตอบสนองต่อคำขอใด ๆ ไม่ได้
ไม่ฝักใฝ่ฝ่ายใด

1
คุณใช้สิ่งนี้กับ localhost หรือไม่?
Dzung Nguyen

คำตอบ:


155

ฉันมีข้อกำหนดเดียวกันกับคุณเกี่ยวกับ API สาธารณะที่ฉันใช้ Rails-api

ฉันยังตั้งค่าส่วนหัวในก่อนตัวกรอง ดูเหมือนว่า:

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'

ดูเหมือนว่าคุณพลาดส่วนหัว Access-Control-Request-Method


นั่นเป็นเรื่องแปลก คุณช่วยให้ข้อมูลเพิ่มเติมเกี่ยวกับข้อผิดพลาดที่คุณได้รับได้หรือไม่
matteo

github.com/cleor41/Cors-Rails4-APIตรวจสอบสิ่งนี้หากคุณไม่รู้ว่าจะวางไว้ตรงไหน
CleoR

8
Access-Control-Request-Method ถูกตั้งค่าในคำร้องขอไม่ตอบสนอง developer.mozilla.org/en-US/docs/Web/HTTP/…
kuboon

19

ดูมิดเดิลแวร์แร็คคอร์ มันจะจัดการกับส่วนหัว CORS ในลักษณะที่กำหนดได้


2
เราใช้แร็คคอร์มาหลายเดือนแล้วและยังไม่พบปัญหาใด ๆ คุณแน่ใจหรือไม่ว่าปัญหาไม่ได้อยู่ที่ฝั่งไคลเอ็นต์
Jef

1
ฉันคิดว่าปัญหาคือส่วนขยายของ Chrome ไม่รองรับ CORS ดังนั้น Origin อาจเป็น Null ฉันจะปิดการใช้งาน CORS โดยสมบูรณ์และตอบสนองต่อคำขอใด ๆ รวมถึงคำขอที่มีต้นกำเนิด Null ได้อย่างไร
ไม่ฝักใฝ่ฝ่ายใด

คุณใช้ส่วนขยาย Chrome อะไร
Jef

1
ฉันกำลังเขียนส่วนขยาย Chrome ที่ต้องการสื่อสารกับแบ็กเอนด์ Rails ของฉัน
ไม่ฝักใฝ่ฝ่ายใด

12

เพียงแค่คุณเพิ่มอัญมณีแร็คคอร์ https://rubygems.org/gems/rack-cors/versions/0.4.0

ขั้นตอนที่ 1: เพิ่มอัญมณีใน Gemfile ของคุณ:

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

จากนั้นบันทึกและเรียกใช้ bundle install

ขั้นตอนที่ 2: อัปเดตไฟล์ config / application.rb ของคุณโดยเพิ่มสิ่งนี้:

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

สำหรับรายละเอียดเพิ่มเติมคุณสามารถไปที่https://github.com/cyu/rack-cors Specailly หากคุณไม่ใช้ราง 5


สำหรับฉัน.insert_before 0สิ่งนั้นสำคัญมาก ก่อนที่ฉันจะใช้config.middleware.useและใช้งานได้จนกว่าฉันต้องการอนุญาต CORS สำหรับpublicไดเรกทอรีของฉันเท่านั้น
สึนามิ

5

ฉันมีปัญหาโดยเฉพาะกับ Chrome เช่นกัน สิ่งที่คุณทำดูเหมือนกับสิ่งที่ฉันทำในใบสมัครของฉัน ข้อแตกต่างเพียงอย่างเดียวคือฉันตอบสนองด้วยชื่อโฮสต์ที่ถูกต้องในส่วนหัว Origin CORS ของฉันไม่ใช่สัญลักษณ์แทน สำหรับฉันแล้วดูเหมือนว่า Chrome จะพิถีพิถันกับเรื่องนี้

การสลับระหว่างการพัฒนาและการผลิตเป็นความเจ็บปวดดังนั้นฉันจึงเขียนฟังก์ชันเล็ก ๆ น้อย ๆ นี้ซึ่งช่วยฉันในโหมดการพัฒนาและในโหมดการผลิตด้วย ทุกสิ่งต่อไปนี้เกิดขึ้นในของฉันapplication_controller.rbเว้นแต่จะระบุไว้เป็นอย่างอื่นมันอาจไม่ใช่วิธีแก้ปัญหาที่ดีที่สุด แต่แร็คคอร์ก็ไม่ได้ผลสำหรับฉันเช่นกันฉันจำไม่ได้ว่าทำไม

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

จากนั้นฉันก็มีสิ่งเล็ก ๆ น้อย ๆ ในตัวฉันapplication_controller.rbเพราะไซต์ของฉันต้องการการเข้าสู่ระบบ:

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

ในของroutes.rbฉันฉันก็มีสิ่งนี้:

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

และวิธีนี้มีลักษณะดังนี้:

def empty
  render :nothing => true
end

1
เพียงเพื่อปิดวงกลม ความยุ่งเหยิงของ CORS ทั้งหมดนี้เกิดขึ้นเฉพาะเมื่อคุณกดปุ่มแบ็คเอนด์การผลิตจากแอปพลิเคชัน localhost ใช่ไหม? สิ่งนี้จะไม่เกิดขึ้นเมื่อทุกอย่างอยู่ในระหว่างการผลิต?
Sebastialonso

2
เฉพาะในกรณีที่แบ็กเอนด์และเว็บแอปโฮสต์อยู่ภายใต้ URL เดียวกัน หากโฮสต์อยู่ภายใต้ URL สองรายการที่ต่างกันโดยสิ้นเชิงสิ่งนี้จะเกิดขึ้นในการผลิต
Christoph Eicke

3

ฉันเคยมีปัญหาที่คล้ายกันมาก่อนซึ่งกลายเป็นเว็บเบราว์เซอร์ (Chrome ในกรณีของฉัน) ที่เป็นปัญหา

หากคุณใช้ chrome ให้ลองเปิดใช้งาน:

สำหรับ Windows:

1) สร้างทางลัดไปยัง Chrome บนเดสก์ท็อปของคุณ คลิกขวาที่ทางลัดแล้วเลือกคุณสมบัติจากนั้นเปลี่ยนเป็นแท็บ "ทางลัด"

2) ในช่อง "เป้าหมาย" ให้ต่อท้ายสิ่งต่อไปนี้: –args –disable-web-security

สำหรับ Mac ให้เปิดหน้าต่างเทอร์มินัลและเรียกใช้จากบรรทัดคำสั่ง: open ~ / Applications / Google \ Chrome.app/ –args –disable-web-security

ข้อมูลข้างต้นจาก:

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


เหตุใดจึงได้รับการโหวตลดลง ฉันมีสถานการณ์คล้ายกับที่อธิบายไว้ในคำถามซึ่งได้รับการแก้ไขโดยการเรียกใช้ Chrome โดยปิดใช้งานความปลอดภัยของเว็บ ปัญหาเกิดขึ้นเมื่อคุณกำลังเรียกใช้เซิร์ฟเวอร์การพัฒนาภายในเครื่อง เห็นได้ชัดว่าคุณจะไม่ปล่อยให้ Chrome ทำงานโดยปิดใช้งานการรักษาความปลอดภัยเว็บเสมอไป
PropertyWebBuilder

สิ่งนี้ไม่ควรลงคะแนนเนื่องจากเขาอธิบายสถานการณ์ได้ถูกต้อง :)
Dzung Nguyen

4
ฉันไม่ได้ทำการลงคะแนน แต่จากคำตอบยังไม่ชัดเจนว่านี่เป็นวิธีแก้ปัญหาเพื่อการพัฒนาเท่านั้น แม้ว่าวิธีนี้อาจแก้ปัญหาได้ในพื้นที่ แต่ก็ไม่สามารถคาดหวังให้ผู้เยี่ยมชมเว็บ / ผู้ใช้ส่วนขยายของคุณทำเช่นนี้ได้ ดังนั้นฉันจะชี้แจงในคำตอบ
nathanvda

1
ไม่มีการลงคะแนนที่นี่เช่นกัน แต่เคยเป็นเช่นนั้นครั้งแรกที่ chrome ทำงานพร้อมกับแฟล็กที่กำหนดทำให้อินสแตนซ์อื่น ๆ ทั้งหมดทำงานในลักษณะเดียวกัน สิ่งที่ต้องระวังให้มาก ทุกอย่างมันง่ายเกินไปที่จะลืมและท่องแบบกะทันหัน
dc5

2

เพิ่งพบกับปัญหานี้ในแอปพลิเคชันรางของฉันในการผลิต คำตอบมากมายที่นี่ให้คำแนะนำและช่วยให้ฉันได้คำตอบที่ได้ผลดีสำหรับฉันในที่สุด

ฉันใช้งาน Nginx และมันก็ง่ายพอที่จะแก้ไขไฟล์my_app.conf (โดยที่my_appคือชื่อแอปของคุณ) คุณสามารถค้นหาไฟล์นี้ได้ใน/etc/nginx/conf.d

หากคุณไม่ได้location / {}แล้วคุณก็สามารถเพิ่มภายใต้server {}แล้วเพิ่มภายใต้add_header 'Access-Control-Allow-Origin' '*';location / {}

รูปแบบสุดท้ายควรมีลักษณะดังนี้:

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

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

-2

ลองกำหนดค่าที่ /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

คุณลืมพูดถึงนักพัฒนาควรเพิ่ม 'แร็คคอร์' ใน Gemfile
Gabriel Lidenor

-2

ใช้ VSC หรือโปรแกรมแก้ไขอื่น ๆ ที่มี Live server ซึ่งจะให้พร็อกซีที่จะช่วยให้คุณใช้ GET หรือ FETCH

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.