為了避免自己網站的資源遭到別人使用與修改,這就是同源政策存在的原因。首先必須要了解何謂同源政策,同源政策所限制的對象是Javascript所發出的跨來源請求,其他送出表單、重新導向、嵌入img等是不受限制的。舉例來說,假設今天有2個網站,一個是Facebook,另一個是個人網誌,在同源政策下,Facebook想要透過Javascript存取個人網誌的文章是不被允許的,同樣的,個人網誌透過Javascript取得Facebook裡的貼文也是不被允許的。
何謂同源
網址判定來源的依據,一個完整的網址會包含Scheme、Domain、Port與Path,若當中的Scheme、Domain與Port相同就會被視為同源。
同樣以 https://cms.aaasec.com.tw/index.php/category/intro/ 為例,判斷下列是否同源。
跨來源資源共用
跨來源資源共用(Cross-Origin Resource Sharing,CORS)是一種透過HTTP Header讓存取其他不同網域資源的機制,當然也必須遵守同源政策,那又要怎麼存取其他網域的資源呢?首先必須要了解,若發出的HTTP請求並非簡單請求,則該請求就是CORS。而CORS會先發出預檢請求(Preflight Request),若伺服器允許才能夠存取資源。
簡單請求:
- 當Post方法的Content-Type為text/plain、multipart/form-data或application/x-www-form-urlencoded。
- 使用Get或Head方法。
- 若設置CORS Header以外的欄位,則不屬於簡單請求。
預檢請求
瀏覽器會先使用Option方法向Server發出預檢請求,若是Server允許,瀏覽器才會開始存取資源。以下會透過簡單的範例解說流程。
第13行:透過Javascript發起請求。
第15行:設定請求對象為http://192.168.10.129:5000/,進行跨站請求。
第17行:設置CORS Header以外的欄位,使它不會是簡單請求。
預檢請求成功
圖中可以發現瀏覽器先以Option向Server發送預檢請求,並且於Server回應的Header得到存取資訊:
- Access-Control-Allow-Headers: test-page
表示請求的Header須包含test-page。 - Acess-Control-Allow-Origin: *
表示可以接受任意來源的請求。
圖中可以發現送出請求的Header確實包含test-page,並且於頁面彈出來自Server回應的時間訊息。
預檢請求失敗
圖中可以發現送出請求被拒絕時並沒有顯示Server回應的時間訊息,並且瀏覽器提示失敗。
圖中可以發現失敗原因是http://192.168.10.128:5000與Server回傳的http://192.168.10.129:5000並不相同。
設定了CORS就安全嗎?
由於預檢請求是由瀏覽器發出,並且也是由瀏覽器阻擋,所以只能防止一般人上網避免遭到CSRF攻擊,所以只要不藉由瀏覽器存取,透過以下範例便能在預檢請求失敗情況下,一樣獲得Server所回傳的時間訊息。
輸出結果:DateTime(129): 2019/03/25 22:53:32
因此,若是要讓資源只能透過特定機器存取,還是藉由IP限制等其他方式較佳。