前言
最近在本地调试时,发现请求接口提示“未登录”,通过分析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也不会发送。