每個 Cookie 都包含鍵/值組合,以及用來控制 Cookie 使用時機和位置的多個屬性。
導入 SameSite
屬性 (定義於 RFC6265bis) 後,您就能宣告 Cookie 是否僅限於第一方或同網站使用情境。請務必瞭解「網站」一詞在此處的確切含義。網站是網域字尾與網域名稱中緊鄰該字尾的部分組合。舉例來說,www.web.dev
網域是 web.dev
網站的一部分。
關鍵字:如果使用者位於 www.web.dev
,並從 static.web.dev
要求圖片,則為同網站要求。
公用字尾清單定義哪些網頁算是位於同一網站。這項功能不只取決於 .com
等頂層網域,還可納入 github.io
等服務。這樣一來,系統就會將 your-project.github.io
和 my-project.github.io
視為不同的網站。
關鍵字:如果使用者位於 your-project.github.io
,並向 my-project.github.io
要求圖片,則為跨網站要求。
使用 SameSite
屬性宣告 Cookie 用途
Cookie 上的 SameSite
屬性提供三種不同的方式來控制這項行為。您可以選擇不指定屬性,也可以使用 Strict
或 Lax
,將 Cookie 限制為同網站要求。
如果您將 SameSite
設為 Strict
,Cookie 只能在第一方情境中傳送,也就是 Cookie 的網站必須與瀏覽器地址列中顯示的網站相符。因此,如果 promo_shown
Cookie 的設定如下:
Set-Cookie: promo_shown=1; SameSite=Strict
當使用者造訪您的網站時,系統會如預期地隨請求傳送 Cookie。不過,如果使用者透過其他網站的連結進入您的網站,系統就不會在該初始要求中傳送 Cookie。這類 Cookie 適用於與初始導覽後方功能相關的 Cookie,例如變更密碼或購物,但對於 promo_shown
這類 Cookie 來說太過嚴格。如果讀者點選連結進入網站,他們會希望系統傳送 Cookie,以便套用偏好設定。
SameSite=Lax
可讓瀏覽器透過這些頂層導覽傳送 Cookie。舉例來說,如果其他網站引用您網站的內容,在本例中是使用您的貓咪相片,並提供您文章的連結,如下所示:
<p>Look at this amazing cat!</p>
<img src="https://blog.example/blog/img/amazing-cat.png" />
<p>Read the <a href="https://blog.example/blog/cat.html">article</a>.</p>
將 Cookie 設為 Lax
,如下所示:
Set-Cookie: promo_shown=1; SameSite=Lax
當瀏覽器為他人的網誌要求 amazing-cat.png
時,您的網站不會傳送 Cookie。不過,如果讀者點選網站上的連結前往 cat.html
,該要求就會包含 Cookie。
建議您以這種方式使用 SameSite
,將影響網站顯示的 Cookie 設為 Lax
,將與使用者操作相關的 Cookie 設為 Strict
。
您也可以將 SameSite
設為 None
,表示您希望在所有情境中傳送 Cookie。如果您提供其他網站使用的服務,例如小工具、內嵌內容、聯盟計畫、廣告或跨多個網站的登入功能,請使用 None
確保意圖明確。
變更預設行為 (不含 SameSite)
瀏覽器支援
SameSite
屬性廣泛支援,但尚未廣泛採用。過去,未設定 SameSite
的 Cookie 預設會在所有情境下傳送,導致使用者容易遭受 CSRF 攻擊,並意外洩漏資訊。為了鼓勵開發人員說明其意圖,並為使用者提供更安全的體驗,IETF 提案「Incrementally Better Cookies」列出了兩項重要變更:
- 沒有
SameSite
屬性的 Cookie 會視為SameSite=Lax
。 - 含有
SameSite=None
的 Cookie 也必須指定Secure
,表示 Cookie 需要安全的環境。
這兩項變更都與已正確實作舊版 SameSite
屬性的瀏覽器回溯相容,也與不支援舊版 SameSite
的瀏覽器回溯相容。這些標記旨在明確說明 Cookie 行為和預期用途,藉此減少開發人員對瀏覽器預設行為的依賴程度。任何不支援 SameSite=None
的用戶端都應忽略該標記。
預設為 SameSite=Lax
如果您傳送 Cookie 時未指定其 SameSite
屬性,瀏覽器會將該 Cookie 視為已設為 SameSite=Lax
。我們仍建議您明確設定 SameSite=Lax
,讓使用者在不同瀏覽器上的體驗更一致。
SameSite=None
必須安全
使用 SameSite=None
建立跨網站 Cookie 時,您也必須將 Cookie 設為 Secure
,才能讓瀏覽器接受:
Set-Cookie: widget_session=abc123; SameSite=None; Secure
如要測試 Chrome 76 的這項行為,請啟用 about://flags/#cookies-without-same-site-must-be-secure
;如要測試 Firefox 69 的這項行為,請在 about:config
中設定 network.cookie.sameSite.noneRequiresSecure
。
建議您盡快將現有的 Cookie 更新為 Secure
。如果您在網站上使用第三方內容服務,請務必確認服務供應商更新 Cookie,並更新網站上的任何程式碼片段或依附元件,確保網站採用新行為。
SameSite
個 Cookie 食譜
如要進一步瞭解如何更新 Cookie,以便成功處理 SameSite=None
的這些變更和瀏覽器行為的差異,請參閱後續文章「SameSite Cookie 食譜」。
感謝 Lily Chen、Malte Ubl、Mike West、Rob Dodson、Tom Steiner 和 Vivek Sekhar 提供意見和回饋。
Cookie 主頁橫幅圖片,由 Pille-Riin Priske 提供,圖片來源:Unsplash