最近因为Chrome升级到80以后,带来了一些新的问题,需要考虑到其带来的影响,其中之一是关于SameSite默认值的改变,本次计划用两次来说明SameSite以及如何进行相关的升级和兼容
1. 基本概念
1.1 SameSite是什么
MDN上有比较完整的描述:
SameSite cookies let servers require that a cookie shouldn't be sent with cross-site (where Site is defined by the registrable domain) requests, which provides some protection against cross-site request forgery attacks (CSRF).
翻译过来,SameSite的作用就是在请求的时候来判断cookie可以跨站传递(和跨域概念有所不同,虽然都是cross-site,自己一开始理解的是跨域,直到得到了同事的提醒才知道这里是指跨站),举个简单的例子,假如现在有两个站点www.a.com
和www.b.com
,如果前者中引用了后者请求,那么在发送请求的时候,是否会携带后者的cookie
到后者的服务器呢?SameSite的作用其实就是对该情况进行描述。
其中对于跨站的理解,那么需要判别同一站点两个地址是否是同一站点,引用一下同事的相关说明:
在绝大部分的情况下,我们可以将同一站点简单理解为常说的 二级域名,所以,samesite所约束的同一站点就是指:同一个二级域名下的各个子域名间的资源属于同一个站点。当然,跨站点就是指不是同一站点的意思。
浏览器判断是否跨站,是利用了Public Suffix List的策略,该策略可以认为是浏览器维护了一系列站点的地址,例如:Mozilla 很久之前维护的这个域名后缀列表,通过规则匹配,则符合同一规则的地址将认为是同一站点,具体详细内容可参见紫云飞:关于SameSite的博客
1.2 SameSite如何使用
目前SameSite有三个常用的值Strict
, Lax
, None
,他们的作用是对跨站请求的cookie做不同程度的限制,而根据请求的不同,其对应关系如下:
设置为
Strict
以后,跨站点就不会再传递该cookie
document.cookie = 'key=value;SameSite=Strict'
设置为
Lax
以后,会限制部分请求cookie的传递
document.cookie = 'key=value;SameSite=Lax'
不对cookie做设置,会在跨站点情况下发送cookie
document.cookie = 'key=value;'
常规模式下以前只有这三种情况,但是SameSite还可以设置为None
,且从Chrome从76版本开始,开始对设置为None
必须和Secure
配合使用,表示为
document.cookie = 'key=value;SameSite=None;Secure'
由于使用了Secure
,则当前站点必须使用https
的安全链接
1.3 为什么本次需要升级
因为从Chrome 80开始,默认会对cookie设置SameSite=Lax
,ChromeLab对此有比较清楚的说明:地址,目前项目中大部分cookie是没有设置任何的SameSite属性,所以可能出现跨站cookie无法传递的情况,需要对这部分内容进行处理,否则,可能出现cookie无法传递导致类似登陆失败问题。
当然,我们可以自行开启和关闭浏览器对于该默认值的设定
chrome://flags/#same-site-by-default-cookies
也可以设置在SameSite=None
的时候,必须使用https
的请求
chrome://flags/#cookies-without-same-site-must-be-secure
1.4 其他
1.4.1 跨站和跨域的区别
补充说一下自己认为跨站和跨域的区别,在做测试的时候,最开始认为是跨域,所以使用两个端口(8080,8081)进行尝试,结果发现不论如何设置,两个站点cookie的传递都是可以正常发起;
之后误打误撞的使用了127.0.0.1和本地局域网IP(172.168.0.xxx)进行尝试,发现居然能使用SameSite的设置了,所以,至少从这个层面上来说,跨域是指对于协议(protcol),域名(host),端口(port)的不同,可能自己的理解也存在偏差,这里如果有更好的理解可以随时私信
2. 具体测试案例
具体例子可参见Github,例子主要是根据了Chrome官方的测试方案,进行了摸索本地如何验证该特性,测试步骤主要包括以下特性验证:
1.使用Chrome浏览器的默认设置,请求结果如何;
2.开启相关Chrome的设置,请求结果如何;
3.开启Chrome设置后,设置SameSite=None
和Secure
,以及开启https
请求后,结果如何
ps: 本次测试使用Chrome80版本
几个注意的细节:
2.1 如何开启https服务
网上存在很多相关资料,所以这里不赘述,具体可参见github的例子
2.2 如何确定cookie是否已经设置相关属性
打开Chrome控制台,切换到Application,查看cookie,会发现如果配置成功,那么cookie最后一列的SameSite会设置相关属性
2.3 关于给cookie增加SameSite属性
通过尝试可以发现cookie增加SameSite属性是针对单个cookie值进行的追加
2.4 开启https后访问地址
开启https访问地址可以发现cookie中增加了SameSite=None的cookie