跨網域存取 Cross-Origin Resource Sharing (CORS) 實作 Request

2018-02-04 Nginx

最近實在太忙碌,今天有點時間把以前實作過 Cross-Origin Resource Sharing (CORS) 的經驗寫下來,在 Web 之間進行串接溝通已經是很稀鬆平常的事情,最一般的狀況是 Server 跟 Server 之間的溝通,這通常沒什麼問題,但是如果 Request 發生在 User Browser 端的時候就會遇到 「Cross Domain Access (跨網域存取)」的問題。

 

這種狀況是因為瀏覽器因為資料安全的因素,替使用者做的安全機制,避免資料被傳送到其他 Web Site (不同網域),所以只要使用者的行為有「誇網域」行為的話就會被阻擋。

 

舉例我有一個 A 網站要傳送 Request 到 B 網站,而 A(a.com) 和 B(b.com) 的網域不同,那麼在 Chrome 的開發者工具則可以看到

XMLHttpRequest cannot load http://b.com Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://a.com’ is therefore not allowed access.

 

這就是被瀏覽器阻擋。

但是實務上還是會有跨網域存取的必要,只要在適當信任範圍內就不會造成 CORS 的問題,所以 W3C 就提供了「Cross-Origin Resource Sharing」的方法,利用 Access-Control-* 系列的 Header 來 Trust Cross Origin 的 Request。

 

  • Access-Control-Allow-Origin (Response Header)
  • Access-Control-Allow-Credentials (Response Header)
  • Access-Control-Expose-Headers (Response Header)
  • Access-Control-Max-Age (Response Header)
  • Access-Control-Allow-Methods (Response Header)
  • Access-Control-Allow-Headers (Response Header)
  • Origin (Request Header)
  • Access-Control-Request-Method (Request Header)
  • Access-Control-Request-Headers (Request Header)

 

 

特別注意的是有些 Header 是 Response 用,有些是 Request 使用

 

Access-Control-Allow-Origin

Access-Control-Allow-Origin 這個 Header 是 CORS 必要使用的,這個 Header 可以讓 Brower 信任來源端的 Domain,

 

在 Nginx 上可以用 add_header 實作,並且加上一些「君子式」的針對副檔名過濾。

server {
  ...
  if ($request_filename ~* \.(js|eot|otf|ttf|woff)$ ) {
    add_header 'Access-Control-Allow-Origin: example.com';
  }
  ...
}

 

但是在使用 Access-Control-Allow-Origin 時要非常小心,如果有許多網站要存取的話可以直接使用 Access-Control-Allow-Origin *,但如果資料過於敏感 (如帳號密碼) 就萬萬不可這樣做,務必要經過白名單的過濾才行。

 

Access-Control-Allow-Methods

這個 Header 是用來處理特殊的 Request 動作,一般性的 Method 都在預設 (根據 Section 版本的更新有所異動),如:

  • OPTIONS
  • GET
  • HEAD
  • POST
  • PUT
  • DELETE
  • TRACE
  • CONNECT
  • extension-method

 

在 Nginx 可以這樣加入其他 Method

server {
  ...
  add_header 'Access-Control-Allow-Methods: POST';
  ...
}

 

Access-Control-Allow-Headers

Access-Control-Allow-Headers 這個 Header 在 CORS 也算常用,如果你有自訂一些 Header 或是 Authorization 的話就要透過 Access-Control-Allow-Headers 來允許。

 

一般你可能在 Browers 看到這類型的錯誤:

Request header Authorization field is not allowed by Access-Control-Allow-Headers in preflight response

這代表 Authorization 不在 Access-Control-Allow-Headers 的允許範圍內,所以被阻擋

 

在 Nginx 加入 Access-Control-Allow-Headers 信任 Authorization Header。

server {
  ...
  add_header 'Access-Control-Allow-Headers: Authorization';
  ...
}

 

以上是一些常用的 CORS 實作,如文中所述 CORS 如果沒弄好很容易會被駭客利用跨網站竊取到使用者資料,所以務必小心!

 

給 Mr. 沙先生一點建議

彙整

分類

展開全部 | 收合全部

License

訂閱 Mr. 沙先生 的文章

輸入你的 email 用於訂閱