什麼是跨來源資源共用?
跨來源資源共用 (CORS) 是整合應用程式的一種機制。CORS 定義了一個方式,在一個網域載入的用戶端 Web 應用程式可以與不同網域中的資源互動。這種機制之所以很有用,是因為複雜的應用程式通常會在用戶端程式碼中參考第三方 API 和資源。例如,您的應用程式可能會使用瀏覽器,從影片平台 API 提取影片、使用公共字型庫中的字型,或顯示全國天氣資料庫的氣象資料。CORS 允許用戶端瀏覽器在傳輸任何資料之前,向第三方伺服器確認某個請求是否得到准許。
為什麼跨來源資源共用很重要?
過去,當網際網路技術剛出現時,會發生跨站請求偽造 (CSRF) 問題。發生該問題時,虛假的用戶端請求從受害者的瀏覽器傳送到另一個應用程式。
例如,受害者登入其銀行應用程式。然後被誘騙在新的瀏覽器標籤中載入外部網站。然後,外部網站使用受害者的 cookie 憑證並將資料轉送給銀行應用程式,假裝是受害者。這樣未經授權的使用者便能夠存取銀行應用程式。
為了防止此類 CSRF 問題,所有瀏覽器現在都實作同源政策。
同源政策
如今,瀏覽器強制用戶端只能向與用戶端 URL 具有相同來源的資源傳送請求。用戶端 URL 的協定、連接埠和主機名稱都應該與它請求的伺服器相符。
以下以一些 URL 為例,比較它們與用戶端 URL http://store.aws.com/dir/page.html 的來源情況。
URL |
성과 |
原因 |
http://store.aws.com/dir2/new.html |
同源 |
只是路徑不同 |
http://store.aws.com/dir/inner/other.html |
同源 |
只是路徑不同 |
https://store.aws.com/page.html |
不同源 |
協定不同 |
http://store.aws.com:81/dir/page.html |
不同源 |
連接埠不同 (http:// 的連接埠預設為 80) |
http://news.aws.com/dir/page.html |
不同源 |
不同主機 |
因此,同源政策非常安全,但對於實際使用案例而言不夠靈活。
跨來源資源共用 (CORS) 是對同源政策的擴展。您需要它來與外部第三方共用授權資源。例如,當您想要從公有或授權的外部 API 中提取資料時,您需要 CORS。如果您希望允許授權的第三方存取您自己的伺服器資源,您也需要 CORS。
跨來源資源共用如何運作?
在標準的網際網路通訊中,瀏覽器向應用程式伺服器傳送 HTTP 請求,接收 HTTP 回應,並顯示相關資料。在瀏覽器術語中,當前瀏覽器 URL 稱為當前來源,第三方 URL 稱為跨來源。
當您發起跨來源請求時,請求與回應的過程如下:
- 瀏覽器在請求中新增一個來源標頭,其中包含有關當前來源的協定、主機和連接埠的資訊
- 伺服器檢查當前的來源標頭並使用請求的資料和 Access-Control-Allow-Origin 標頭進行回應
- 瀏覽器看到存取控制請求標頭並然後與用戶端應用程式分享返回的資料
但如果伺服器不允許跨來源存取,它會返回一條錯誤訊息。
跨來源資源共用範例
以 https://news.example.com 這個網站為例。此網站想要透過 API 存取位於 partner-api.com 的資源。
https://partner-api.com 的開發人員首先在其伺服器上設定跨來源資源共用 (CORS) 標頭,方法是將 new.example.com 新增到允許的來源清單。他們透過將以下內容新增到他們的伺服器組態檔案來做到這一點。
Access-Control-Allow-Origin: https://news.example.com
設定 CORS 存取後,news.example.com 便可以從 partner-api.com 請求資源。對於每個請求,partner-api.com 將以 Access-Control-Allow-Credentials : "true" 進行回應。 然後瀏覽器便會知道相關通訊已得到授權並允許跨來源存取。
如果您想要向多個來源授予存取權限,請使用逗號分隔的清單,您還可以使用萬用字元 (如 *) 來向所有人授予存取權限。
什麼是 CORS 預檢請求?
在 HTTP 中,請求方法是用戶端希望伺服器執行的資料操作。常見的 HTTP 方法包括 GET、POST、PUT 和 DELETE。
在常規的跨來源資源共用 (CORS) 互動中,瀏覽器會同時傳送請求和存取控制標頭。這些請求通常是 GET 資料請求,這類請求被認為是低風險的。
然而,一些 HTTP 請求被認為是複雜的,在請求實際傳送之前需要伺服器確認。預核准程序稱為預檢請求。
複雜的跨來源請求
如果跨來源請求使用以下任何一項,則屬於複雜請求:
- GET、POST 或 HEAD 之外的方法
- Accept-Language、Accept 或 Content-Language 之外的標頭
- multipart/form-data、application/x-www-form-urlencoded 或 text/plain 之外的 Content-Type 標頭
例如,刪除或修改現有資料的請求被認為是複雜請求。
預檢請求的運作方式
如果需要,瀏覽器會建立預檢請求。這是一個 OPTIONS 請求,如下所示。
OPTIONS /data HTTP/1.1 來源:https://example.com Access-Control-Request-Method: DELETE |
瀏覽器會在傳送實際請求訊息之前傳送該預檢請求。伺服器必須回應該預檢請求,回以有關伺其願意從用戶端 URL 接受的跨來源請求的資訊。伺服器回應標頭必須包含以下內容:
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- Access-Control-Allow-Origin
下面給出了一個伺服器回應範例。
HTTP/1.1 200 OK Access-Control-Allow-Headers: Content-Type Access-Control-Allow-Origin: https://news.example.com Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS |
預檢回應有時包含一個額外的 Access-Control-Max-Age 標頭。此指標指定瀏覽器快取預檢結果的持續時間 (以秒為單位)。快取允許瀏覽器在不同預檢請求之間傳送數個複雜的請求。在 max-age 指定的時間過去之前,瀏覽器不必傳送新的預檢請求。
CORS 和 JSONP 有什麼區別?
JSON with Padding (JSONP) 是一種歷史悠久的技術,它允許在不同網域上執行的 Web 應用程式之間進行通訊。
使用 JSONP 時,您可以在用戶端頁面中使用 HTML 指令碼標籤。指令碼標籤會載入外部 JavaScript 檔案或直接在 HTML 頁面中嵌入 JavaScript 程式碼。由於指令碼不受同源政策的約束,您便可以透過 JavaScript 程式碼擷取跨來源的資料。
但資料必須是 JSON 格式。此外,JSONP 不如跨來源資源共�� (CORS) 安全,因為提供的資料安全與否全憑外部網域的可信度。
現代瀏覽器新增了一些安全功能,因此包含 JSONP 的舊程式碼已不再適用。CORS 是當前用於跨來源存取控制的全球 Web 標準。
CORS 最佳實務有哪些?
在伺服器上設定跨來源資源共用 (CORS) 時,您應注意以下事項。
定義適當的存取清單
最好始終使用逗號分隔清單來向個別網域授予存取權限。除非您想公開 API,否則請避免使用萬用字元。使用萬用字元和規則運算式可能會產生漏洞。
例如,假設您編寫了一個規則運算式,向字尾為 permitted-website.com 的所有網站授予存取權限。透過這個表達式,您向 api.permitted-website.com 和 news.permitted-website.com 授予了存取權限。但您也在無意中向未經授權的網站授予了存取權限,例如使用 maliciouspermitted-website.com 等網域的網站。
避免在清單中使用 null 來源
某些瀏覽器在某些情況下 (例如檔案請求或來自本機主機的請求) 會在請求標頭中傳送值 null。
但您不應在存取清單中包含 null 值。它還會引入安全風險,因為包含 null 標頭的未經授權的請求可能會取得存取權限。
AWS 如何支援您的 CORS 需求?
我們的許多服務都內建了對跨來源資源共用 (CORS) 的支援。因此,您可以控制對 Amazon Web Services (AWS) 上託管的 API 和資源的跨來源存取。
以下是一些支援 CORS 的 AWS 服務:
- Amazon Simple Storage Service (Amazon S3) 是一種物件儲存服務,提供符合成本效益的各種儲存類別,能夠所有資料儲存使用案例的需求。Amazon S3 允許您建立一個 CORS 組態文件,並在其中設定規則,用於識別允許存取您的 S3 資料的來源、每個來源支援的操作 (HTTP 方法) 以及其他特定於操作的資訊。您最多可以向組態新增 100 條規則。
- Amazon API Gateway 是一種全受管的服務,可讓您輕鬆地建立、發佈、維護、監控和保護任何規模的 API。只需在 Amazon API Gateway 主控台中按一下,您就可以為 REST API 啟用 CORS。
立即建立帳戶,開始使用在 AWS 上使用 API。