Caddy 實戰(九)- 設置頭信息實現跨域

在前端開發中,會通過 fetch 發起網絡請求獲取數據,然後再顯示到頁面上,這也就是我們常說的前後端分離。

但是受限於瀏覽器的同源策略, fetch 是不能跨域訪問的,這時候就需要我們設置服務端響應的頭信息,來達到跨域的目的,而 Caddy 的反向代理,天生就具備這個能力。

什麼是同源策略

同源策略是瀏覽器的一項非常重要的安全策略,它用於限制一個 origin 的文檔或者它加載的腳本如何能與另一個源的資源進行交互。它能幫助阻隔惡意文檔,減少可能被攻擊的媒介。

我們看下它的定義:

同源策略是指在 Web 瀏覽器中,允許某個網頁腳本訪問另一個網頁的數據,但前提是這兩個網頁必須有相同的 URI、主機名和端口號,一旦兩個網站滿足上述條件,這兩個網站就被認定爲具有相同來源

同源策略對 Web 應用程序具有特殊意義,因爲 Web 應用程序廣泛依賴於 HTTP cookie 來維持用戶會話,所以必須將不相關網站嚴格分隔,以防止丟失數據泄露。

頭信息設置

在 Caddy 的反向代理中,爲我們提供了兩個指令來設置請求頭和響應頭的信息,他們分別是 header_up 和 header_down,他們的指令設置規則如下所示:

reverse_proxy [<matcher>] [<upstreams...>] {
    # backends
    to <upstreams...>
    ...
    # header manipulation
    header_up   [+|-]<field> [<value|regexp> [<replacement>]]
    header_down [+|-]<field> [<value|regexp> [<replacement>]]
}
  1. header_up : 用於添加、移除和設置客戶端到上游主機(後端)的請求頭信息。也就是說利用它,可以修改客戶端請求的頭信息,然後再傳給上游後端服務。看到它後面的 +|- 表達式了嗎? + 表示添加一個頭信息, - 表示移除一個頭信息,都沒有的時候表示設置一個頭信息。可以同時有多個header_up 。

  2. header_down : 和header_up 的作用一樣,只不過它是用於修改後端服務響應的頭信息,然後再傳給客戶端,方向正好是反的。

只介紹使用,可能會覺得有點繞,下面我們通過一個示例來看下就明白了,和我們平時設置頭信息差不多的。

https://example.com {
   reverse_proxy /path http://localhost:54321 {
      header_up Host {host}
      header_up X-Real-IP {remote}
      header_up X-Forwarded-For {remote}
      header_up X-Forwarded-Port {server_port}
      header_up X-Forwarded-Proto "http"
   }
}

以上就是一個重新設置 Host、X-Real-IP 等請求頭的示例,通過 header_up 設置,一行設置一個,非常簡單。
這裏需要留意的是 {host} 這些佔位符,他們是 Caddy 預定義的,可以理解爲一個變量,可以在 Caddyfile 中使用,Nginx 也有類似的佔位符,只不過是以 $ 開頭的。

實現跨域訪問

無法跨域的時候,瀏覽器會返回 403 的錯誤:No 'Access-Control-Allow-Origin' header is present on the requested resource,從這個我們就能看到需要設置 Access-Control-Allow-Origin 這個頭信息,而且是返回的響應頭信息,下面我們看下如何在 Caddy 中配置跨域訪問。

https://example.com {
   reverse_proxy /path http://localhost:54321 {
      header_up Host {http.reverse_proxy.upstream.hostport} 
      header_down Access-Control-Allow-Headers * 
      header_down Access-Control-Allow-Origin *
   }
}

以上實現跨域的重點在於header_down 的設置,這裏的header_up 也一種比較好的安全措施,後端可以根據 Host 校驗請求是否合法。
以上設置後,就可以跨域訪問了,非常簡單。

小結

跨域只是頭信息設置的一種使用場景,其他還有很多,結合頭信息,可以自由發揮使用,從這個也可以發現,相比 Nginx,Caddy 還是比較輕的。

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