前言
最近在本地調試時,發現請求接口提示“未登錄”,通過分析HTTP請求報文發現未攜帶登錄狀態的Cookie:
PS:登錄狀態Cookie名是TEST
再進一步分析,發現Cookie的屬性SameSite的值是Lax:
在web.config里設置sameSite="None"即可:
<system.web> <httpCookies sameSite="None"/> <sessionState cookieSameSite="None" /> <authentication mode="Forms"> <forms cookieSameSite="None" /> </authentication>
SameSite的作用
SameSite Cookie是用於防止CSRF攻擊的。
因為HTTP是無狀態的,所以以前的網站是沒有登錄這個概念。自從Cookie面世后,絕大多數的網站采用Cookie來記錄用戶狀態。Cookie是個好東西,但它不安全,其中一個原因是因為Cookie最初被設計成了允許第三方網站發起的請求中攜帶,CSRF攻擊就是利用了Cookie的這一“弱點”。
防止CSRF攻擊的辦法已經有CSRF token校驗和Referer請求頭校驗。為了從源頭上解決這個問題,Google起草了一份草案來改進HTTP協議,那就是為Set-Cookie響應頭新增SameSite屬性,它用來標明這個Cookie是個“同站Cookie”,同站Cookie只能作為第一方Cookie,不能作為第三方Cookie,SameSite有兩個屬性值:Strict和Lax。
SameSite=Strict:
嚴格模式,表明這個Cookie在任何情況下都不可能作為第三方Cookie,絕無例外。比如說假設b.com設置了如下Cookie:
Set-Cookie: aaa=1; SameSite=Strict Set-Cookie: bbb=2
你在a.com下發起的對b.com的任意請求中,aaa這個Cookie都不會被包含在Cookie的請求頭中,但bbb會。
SameSite=Lax:
寬松模式,比Strict放寬了點限制:假如這個請求是改變了當前頁面或者打開了新頁面,且同時是個GET請求(從語義上說GET是讀取操作,比POST更安全),則這個Cookie可以作為第三方Cookie。比如說假設b.com設置了如下Cookie:
Set-Cookie: aaa=1; SameSite=Strict Set-Cookie: bbb=2; SameSite=Lax Set-Cookie: ccc=3
當用戶從a.com點擊鏈接進入b.com時,aaa這個Cookie不會被包含在Cookie請求頭中,但bbb和ccc會,也就是說用戶在不同網站之間通過鏈接跳轉是不受影響了。但假如這個請求從a.com發起的對b.com的異步請求,或者頁面跳轉是通過表單的Post提交觸發的,則bbb也不會發送。