一、關於SameSite的介紹
1. 什麼是SameSite?
SameSite是瀏覽器請求中Set-Cookie響應頭新增的一種屬性,它用來標明這個 cookie 是否是“同站 cookie”,同站 cookie 只能在本域名中使用的cookie,不能作為第三方 cookie。
Chrome 51 開始,瀏覽器的 Cookie 新增加了一個SameSite屬性,用來防止 CSRF 攻擊和使用者追蹤。該屬性起初是由Google 起草的一份草案用來來改進 HTTP 協議的。
2. 為什麼要用SameSite?
用來防止 CSRF 攻擊和使用者追蹤。Cookie 往往用來儲存使用者的身份資訊,惡意網站可以設法偽造帶有正確 Cookie 的 HTTP 請求,這就是 CSRF 攻擊。
3. 在.Net Core3.1中如何使用SameSite?
使用者想要在.Net Core3.1中使用該屬性(以SameSite=None為例),則應在Startup.cs中配置以下程式碼:
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.None;
});
二、使用SameSite時的具體使用
在.Net Core3.1中使用SameSite屬性應注意以下幾點:
(1)Strict 最為嚴格,完全禁止第三方 Cookie,跨站點時,任何情況下都不會傳送 Cookie。換言之,只有當前網頁的 URL 與請求目標一致,才會帶上 Cookie。
(2) Lax
規則稍稍放寬,大多數情況也是不傳送第三方 Cookie,但是導航到目標網址的 Get 請求除外。
(3)Chrome 計劃將Lax
變為預設設定。這時,網站可以選擇顯式關閉SameSite
屬性,將其設為None (對舊版瀏覽器無效,因為舊版瀏覽器沒有該值)
。不過,前提是必須同時設定Secure
屬性(Cookie 只能通過 HTTPS 協議傳送),否則無效。
下面的設定無效
Set-Cookie: widget_session=abc123; SameSite=None
//瀏覽器警告提示
下面的設定有效
Set-Cookie: widget_session=abc123; SameSite=None; Secure
(4)Unspecified表示不指定SameSite屬性。這意味著,瀏覽器不會將 SameSite 屬性新增到Set-Cookie中並且客戶端將使用其預設行為 (對舊版瀏覽器無效,因為舊版瀏覽器沒有該值) 。
(5)設定Secure屬性,該屬性在SameSite=None的場景下使用(以SameAsRequest為例)
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.Secure = CookieSecurePolicy.SameAsRequest;
});
該屬性配置的列舉值有以下幾個:
SameAsRequest:如果提供 cookie 的 URI 是 HTTPS,則 cookie 僅會在後續的 HTTPS 請求上返回到伺服器。 否則,如果提供 cookie 的 URI 為 HTTP,則 cookie 將在所有 HTTP 和 HTTPS 請求上返回到伺服器。 此值可確保已部署伺服器上的所有經過身份驗證的請求使用 HTTPS,還支援將 HTTP 用於本地主機開發和不支援 HTTPS 的伺服器。
Always:Secure 始終標記為 true。 當登入頁以及需要身份驗證標識的所有後續頁是 HTTPS 時,請使用此值。 本地開發也需要使用 HTTPS URL 來完成。
None:Secure 未標記為 true。 當登入頁為 HTTPS,但站點上的其他 HTTP 頁也需要身份驗證資訊時,請使用此值。 不建議使用此設定,因為本地網路或無線連線中的其他計算機可能會觀察到並使用隨 HTTP 請求提供的身份驗證資訊。
三、遇到的問題
按照SameSite=None的解釋,一是這表示允許Cookie的使用,二是必須配合Secure的設定。
那麼當配置Secure的時候,按照文件的解釋,配置為CookieSecurePolicy.SameAsRequest時,無論是https還是http的場景下,使用者登入應該都是沒有問題的(因為使用者登入資訊存在cookie中了)。
但實際上以上我的配置並不生效,瀏覽器總是提示
說明沒有標記secure成功(此時瀏覽器用不了cookie,系統總是會跳到登入頁面)!
我也查了一下資料,說是這種情況Cookie 只能通過 HTTPS 協議傳送,我也確實是證實了在https下是可以正常登入的。
具體是什麼原因,我也不知道,也可能就是規定這麼用,這裡有待大神指點!!!
四、解決辦法
1. 把SameSite設定為了Unspecified,此時瀏覽器不存在SameSite屬性,就不會出現cookie的任何問題。
2. 把域名搞成https,然後SameSite=None配合Secure=SameAsRequest使用,也可以正常使用cookie
本人小白,大神勿噴!