Posted on June 16, 2015
By Karun Siritheerathamrong
Cross Origin Resource Sharing (CORS) คือกลไกที่ทำให้เว็บเซิร์ฟเวอร์สามารถอนุญาต หรือไม่อนุญาต การร้องขอทรัพยากรใดๆ ในหน้าเว็บ ที่ถูกเรียกมาจากโดเมนอื่น ที่ไม่ใช่โดเมนที่หน้าเว็บนั้นอยู่
ตัวอย่างการใช้งานทั่วไป
– หน้าเว็บใดๆ ในเว็บไซต์ xyz.com มีการเรียกไฟล์ฟอนต์ และรูปภาพจาก hahaha.com แล้วเว็บ hahaha.com สามารถใช้ CORS เพื่อไม่อนุญาตให้เว็บอื่นๆ ที่ไม่ได้มาจากโดเมน hahaha.com สามารถเข้าถึงไฟล์ในเว็บได้
– เว็บ api.mydomain.com จะยอมรับเฉพาะคำร้องจากโดเมน mydomain.com และ myfrienddomain.com เท่านั้น ก็สามารถใช้ CORS เพื่ออนุญาตเฉพาะบางโดเมนได้
แม้การเปิดใช้งาน CORS จะช่วยลดปัญหาการเรียกใช้ทรัพยากรข้ามโดเมนหรือการเข้าถึงที่ไม่ได้รับอนุญาตได้ก็ตาม แต่การจะตั้งค่าให้เครื่องเซิร์ฟเวอร์รองรับการใช้งาน CORS ได้ก็ค่อนข้างยุ่งยากพอสมควร ดูจากมาตรฐานของ CORS จาก W3C
แม้กระทั่ง Rails ที่เป็น Web Framework ที่ทรงพลังก็ยังไม่ได้มีฟีเจอร์ที่สามารถเปิดใช้งาน CORS ได้มาให้ตั้งแต่แรก ครั้นจะทำการ implement ตามมาตรฐานของ W3C ก็ดูจะเป็นเรื่องที่ยุ่งยากเกินไป
จึงมีนักพัฒนาสร้างเจมชื่อ “rack-cors” ขึ้นมา ซึ่งเป็น Rack middleware และทำหน้าที่จัดการการตั้งค่า รวมถึงการจัดการการรับ-ส่ง http header ให้เราเสร็จสรรพ
วิธีการใช้งานก็แสนง่ายดาย
1. เพิ่ม
[code language="ruby"]
gem 'rack-cors', require: 'rack/cors'
[/code]
เข้าไปใน Gemfile
2. สร้างไฟล์ config/initializers/rack_cors.rb และภายในมีเนื้อหาดังนี้
[code language="ruby"]
Rails.application.config.middleware.insert_before 0, "Rack::Cors", logger: (-> { Rails.logger }) do
# From any origin
allow do
origins '*'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :head, :options]
end
end
[/code]
origins ‘*’ หมายถึง ให้อนุญาตการร้องขอจากที่ใดๆ
resource ‘*’ หมายถึง อนุญาตให้เข้าถึงทรัพยากรใดๆ (และรวมถึง url ใดๆ ด้วย)
แค่นี้ก็สามารถใช้งาน CORS กับ Rails ได้แล้ว
ตัวอย่างอื่น
อนุญาตให้ localhost:3000 และ 127.0.0.1:3000 และเครื่องจาก 192.168.0.0/24 สามารถเข้าถึง /file/list_all และ /file/at/* ได้ พร้อมทั้งตั้งค่า Custom Headers ต่างๆ ตามต้องการ
แต่จากที่อื่นๆ จะอนุญาตให้เข้าถึงไฟล์ใดๆ จาก /public/ เท่านั้น
[code language="ruby"]
Rails.application.config.middleware.insert_before 0, "Rack::Cors", logger: (-> { Rails.logger }) do
allow do
    origins 'localhost:3000', '127.0.0.1:3000',
            /http:\/\/192\.168\.0\.\d{1,3}(:\d+)?/
            # regular expressions can be used here
    resource '/file/list_all/', :headers => 'x-domain-token'
    resource '/file/at/*',
        :methods => [:get, :post, :put, :delete, :options],
        :headers => 'x-domain-token',
        :expose  => ['Some-Custom-Response-Header'],
        :max_age => 600
        # headers to expose
  end
  allow do
    origins '*'
    resource '/public/*', :headers => :any, :methods => :get
  end
end
[/code]
ง่ายมากเลยใช่ไหมล่ะครับ 🙂