大家好,我是年年!
今天介绍的是三方cookie相关的内容,本文会讲清:
- 什么是三方cookie?
- same-site的变化是什么,对我们的业务有什么影响?
- 为什么有了same-site,还需要same-party?
文章首发在我的公众号:前端私教年年
什么是三方cookie
三方指的是非同站,这个同站和同源协议中的源origin
不同,它的要求更宽松。
同源协议中的源是由「协议+域名+端口」三者一起定义的,有一个不同就不算同源,而同站只受域名的约束,并且还不要求一模一样——只要「有效顶级域名+二级域名」相同,都算同站。
有效顶级域名是由Mozilla维护的一份表格,其中包括.com
、.co.uk
、.github.io
等。所以ai.taobao.com和www.taobao.com是同站的,因为它们的顶级域名(.com)+二级域名(.taobao)相同。
现在知道了什么是站,就可以很简单区分了:
打开开发者工具的application,domain一列中显示和当前域名不同的就是三方cookie
如何携带三方cookie
cookie的携带是浏览器自动的操作,规则是「不认来源,只看目的」,下面会讲清这句话的意思。
cookie下发
首先,需要先了解cookie的下发,服务端会将其下发到浏览器,方法是通过响应头中的set-cookie
字段
里面还包括一些配置属性,关键的是其中的domain
domain
指定cookie未来使用时,可以被携带到哪些域名。其值可以设置为当前服务端的父级域名或其本身,比如ai.taobao.com
设置的cookie的domain可以为.taobao.com
,所设置值的所有子域名都可以使用,比如www.taobao.com
。
如果不设置,会默认为当前域名ai.taobao.com
,并且只有自己可以使用,子域名sub.ai.taobao.com
都不能使用,适用范围就小了很多,所以一般都会设置。
但是不能设置为跨站点的.baidu.com
,也不能是顶级域名.com
。
其余的属性还有这些:
- path:指定cookie未来使用时,可以被携带到合法域名的哪些URI。和domain很像,也只能设置为当前路径的父级路径或其本身,设置值的所有子路径都可以访问。
- expire/max-age: 指定cookie的有效期,其中expire是一个绝对时间,max-age是相对时间,单位是秒,两者同时存在时,max-age优先级更高;如果两者都没有,则为会话级别的cookie,即用户关闭浏览器时失效。
Set-Cookie: id=nian; Expires=Wed, 30 Aug 2022 00:00:00 GMT; Max-Age=3600
- secure:只能在HTTPS环境中被下发以及携带
- http-only:禁止客户端脚本通过 document.cookie 获取 cookie,避免 XSS 攻击。
- 还有下面会重点讲解的same-site和same-party
Cookie携带
上面提到,cookie的domain字段很关键,它规定请求哪些域名才会携带,注意,这里指的是请求目的地的域名。
举个例子,首先我通过响应头在浏览器中设置了一个cookie,domain是.a.com
set-cookie: id=nian; domain=.a.com;
现在有三个请求:
- 网页
www.a.com/index.html
的前端页面,去请求接口www.b.com/api
- 网页
www.b.com/index.html
的前端页面,去请求接口www.a.com/api
- 网页
www.a.com/index.html
的前端页面,去请求接口www.a.com/api
有点绕,可以暂停思考10秒,哪个请求会带上之前设置的cookie呢?
答案是2、3都会带上cookie,因为cookie的取用规则是去看请求的目的地,2、3请求的都是www.a.com/api
命中domain=.a.com
规则。
这就是「不认来源,只看目的」的意思,不管请求来源是哪里,只要请求的目的是a站,cookie都会携带上。
通过这个案例也可以再回顾一下:3的这种情况的叫第一方cookie,2的这种情况叫第三方cookie。
限制三方cookie的携带
「不认来源,只看目的」规矩在2020年开始被打破,这种变化体现在浏览器将same-site:lax
设置为默认属性。
chrome操作比较平缓,目前可以手动设置same-site:none
恢复之前规则。
但在safari中如果这样设置,会被当作same-site:strict
可以看到,在safari中使用的全是第一方cookie,直观的体验就是在天猫登录完,打开淘宝,还需要再登录一次。
也就是说现在cookie的取用是「既看来源,又看目的」了。
SameSite
上面提到的same-site是cookie的一个属性,它制约第三方cookie的携带,其值有三个none
、strict
、lax
。
strict
代表完全禁止三方cookie,这是最严格防护,可以避免被CSRF攻击,但缺点也很明显,像天猫、淘宝这种同属一个主体运营的网站不得不重复登录;none
代表完全不做限制,即之前「不认来源,只看目的」的cookie取用原则;Lax
则是折中,在某些情况下会限制三方cookie的携带,某些情况又放行,这也是浏览器的默认值(包括safari)。在safari,same-site的默认值是lax,如果把它设置为same-site:none,会适得其反,被当作strict处理
SameSite的修改
可以这么理解,浏览器将same-site的默认值从
none
调整到了lax
same-site:lax的具体规则如下:
类型 | 例子 | 是否发送 |
---|---|---|
a链接 | <a href="..."></a> | 发送 |
预加载 | <link rel="prerender" href="..."/> | 发送 |
GET 表单 | <form method="GET" action="..."> | 发送 |
POST 表单 | <form method="POST" action="..."> | 不发送 |
iframe | <iframe src="..."></iframe> | 不发送 |
AJAX | axios.post | 不发送 |
图片 | <img src="..."></a> | 不发送 |
而在这之前是会全部发送的。
SameSite修改带来的影响
像a链接这种,没有受到影响,依旧会带上三方cookie,这样可以保证从百度搜索中打开淘宝,是有登录状态的。
但是对大部分业务的影响是巨大的,比如监控埋点系统。
埋点监控SDK是用图片的src去做请求的发送的,从上面的表格可知,变成lax后默认不发送了,这时用户的身份便无法确认,UV也没法统计了。
为什么埋点监控用会图片的src,之前详细写过一篇文章,戳这里
为了解决这些问题,大部分公司目前的解决方案是设置same-site:none
并且配合secure
,就可以像以往一样,继续携带第三方cookie。
但这不是版本答案。
SameParty
上面说到,为了绕开浏览器对三方cookie的限制,保障业务的正常,我们的解决方式是把same-site又设置回none。
但这不是长久之策,一来,浏览器把same-site的默认值从从none
调整到lax
可以避免CSRF攻击,保障安全,可我们为了业务正常运行,却又走了回头路;二来,chrome承诺2022年,也就是今年,会全面禁用三方cookie,届时和在safari一样,我们没法再用这种方法去hack。
如果我们不想使用same-site:none,或者说,未来用不了这种方式了,same-party将是我们的唯一选择。
什么是 SameParty
继续沿用阿里系的例子,same-party可以把.taobao.com
、.tmall.com
和.alimama.com
三个站合起来,它们设置的cookie在这个集合内部不会被当作第三方cookie对待。
首先需要定义First-Party集合:在.taobao.com
、.tmall.com
和.alimama.com
三个站的服务器下都加一个配置文件,放在/.well-know/
目录下,命名为first-party-set
。
其中一个是“组长”,暂定为.taobao.com
,在它的的服务器下写入
// /.well-know/first-party-set
{
"owner": ".taobao.com",
"members": [".tmall.com", ".alimama.com"]
}
另外两个是组员:
// /.well-know/first-party-set
{
"owner": ".taobao.com",
}
并且,在下发cookie时,需要注明same-party属性:
Set-Cookie: id=nian; SameParty; Secure; SameSite=Lax; domain=.taobao.com
这样,我们打开.tmall.com
的网站,向.taobao.com
发起AJAX请求,都会带上这个cookie,即使当前的same-site属性是lax,因为这集合中的三个域名都会被当作一个站对待,也就是说,在浏览器眼中,这个cookie现在就是第一方cookie。
而不在集合中的baidu.com
发起的AJAX请求则不会带上。
需要注意的是,使用same-party属性时,必须要同时使用https(secure属性),并且same-site不能是strict。
结语
对三方cookie的限制一是为了浏览器安全,但在国外推动的更重要原因是个人的隐私安全。但不论是出于什么目的,这种改变都会对当前的业务架构造成很大的影响。
same-site:lax
变成默认是一个暂时的预警,它限制了特定场景下的第三方cookie使用。目前处于比较柔和的过渡期,因为在大部分浏览器中,我们可以简单地将它调整回same-site:none
来解除这些限制,和以前一样畅通无阻。
但未来这项限制终将无法脱下,same-party
才是版本答案,有了它,我们可以灵活定义哪些站属于业务意义上的“第一方”,哪些才是我们想要的“第三方”。
如果觉得这篇文章对你有帮助,请点个赞还有关注吧!
你的支持是我创作的动力❤️
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。