一次性搞懂跨域 CORS

可能以前見過上面的內容?可能... 而且可能見過很多次..

有數百萬篇文章解釋如何修復上述錯誤,但究竟什麼是 “跨域資源共享”(CORS)以及爲什麼它存在?

 爲什麼?

讓我們首先通過一個場景來回答爲什麼的問題,以及它在不同時間點會如何發展。

想象一下:您登錄 bank.com ,這是您的銀行服務。登錄後,將在您的瀏覽器中存儲一個 “會話 cookie”(會話 cookie 基本上告訴 bank.com 背後的服務器,您的瀏覽器現在已登錄到您的帳戶)。現在,對 bank.com 的所有未來請求都將包含此 cookie,並且它可以正確響應,知道您已登錄。
好的,現在你決定檢查你的郵箱。你看到一封可疑的電子郵件,當然,你決定點擊裏面的鏈接,它會把你發送到 attack.com 。接着,這個網站向 bank.com 發送一個請求,以獲取你的銀行詳細信息。請記住,由於那個會話 cookie, bank.com 仍然認爲你已經登錄…… 那個 cookie 存儲在你的瀏覽器上。對於 bank.com 背後的服務器來說,它看起來就像你正常請求你的銀行詳細信息一樣,所以它把它們發送回來。現在 attack.com 已經可以訪問這些信息,並惡意地將它們存儲在其他地方。

人們意識到這是不好的,因此瀏覽器採用了 SOP(同源策略),如果您的瀏覽器注意到您試圖從 bank.com 以外的任何地方發出請求,它們將被阻止。現在,要意識到這一點很重要——這是一個基於瀏覽器的策略。 bank.com 實際上無法判斷請求來自何處,因此它無法很好地防範 CSRF 等攻擊。您正在使用的瀏覽器會介入,並基本上表示,如果您似乎正在請求一個來源(方案 + 域名 + 端口,https//foo.com:4000,http//bar.org:3000 等... 基本上是 URL),它只會爲相同的來源發送這些請求。

現在,這很棒,但它非常有限。我的意思是,公共 API 根本無法工作。除非您使用某種代理解決方案,否則無法從它們請求數據。

CSRF

這是個事實:服務器可以在某種程度上知道請求來自哪裏。有一個 “Origin” 頭部,請求應該有這個頭部,展示了請求的來源。例如,在上面的例子中,請求會看起來像這樣。

Request to -----> bank.com  
{  
  Headers: { Origin: http://attack.com }  
}

在理論上,應該檢查這一點,以確保它只響應源有意義的請求。通常情況下是這樣的,所以 SOP 似乎有點限制。
這就是 CORS 發揮作用的地方。

 跨域資源共享 CORS

當來自 example.com 的 Web 應用程序嘗試從 bank.com 請求資源時,瀏覽器會自動在請求中包含一個 Origin 頭部,指示請求的來源( example.com )。這是關鍵的部分: bank.com 的服務器可以檢查這個 Origin 頭部,根據自己的 CORS 策略決定是否允許或拒絕請求,而不是直接阻止這種跨源請求。

如果 bank.com 認爲 example.com 值得信賴,或者請求的資源應該是公開可訪問的,它可以使用特定的 CORS 頭部進行響應,比如 Access-Control-Allow-Origin ,指示允許訪問資源的來源。這個頭部可能被設置爲 http://example.com ,明確允許這個來源,或者 * 用於任何來源都可以訪問的公共資源。

當然,瀏覽器可以方便地完成所有這些。如果有任何錯誤,你會收到那個討厭的錯誤。

現在... 如果請求沒有 Origin 標頭怎麼辦?如果它有一堆其他標頭,而且沒有使用基本的 HTTP 方法呢?

在這些情況下,處理 CORS 變得更加複雜,因爲它不再是一個 “簡單請求”。這就是 CORS 中“預檢” 請求概念發揮作用的地方。

 預檢 Preflight

對於某些可能修改服務器上數據的請求類型——使用 PUT、DELETE 等 HTTP 方法或使用不會自動包含在每個請求中的標頭的請求——瀏覽器在實際發出請求之前會先發送一個 “預檢” 請求。這個預檢請求是一個 HTTP OPTIONS 請求,其目的是與服務器確認實際請求是否安全發送。

預檢請求包括描述實際請求的 HTTP 方法和標頭的標頭。接下來會發生什麼:

    1. 服務器響應:如果服務器支持 CORS 策略和實際請求,則會用頭部響應預檢請求,指示允許的方法和頭部。這可能包括頭部如 Access-Control-Allow-Methods 和 Access-Control-Allow-Headers 。
    1. 瀏覽器決策:根據服務器對預檢請求的響應,瀏覽器決定是否繼續實際請求。如果服務器的響應表明請求被允許,瀏覽器會發送它;如果不允許,瀏覽器會阻止請求,您將看到與 CORS 相關的錯誤。

 結論

希望現在你對 CORS 有了更多的瞭解。我認爲最重要的一點是要意識到這都是瀏覽器策略,你的服務器必須編碼以符合它。這是爲了保護你的安全。如果你正在使用 Chrome,你不應該太擔心點擊錯誤的鏈接(當然,你仍然應該有點擔心: D)。然而,這並非是一個絕對可靠的策略。如果你使用一些不符合標準的第三方瀏覽器,所有這些都將被拋棄。

作者:Oleks Gorpynich

譯者:加布

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/efLmtDRLGsHFkx7ZLGqeJw