2
头图

大家好,我是年年!

今天介绍的是三方cookie相关的内容,本文会讲清:

  1. 什么是三方cookie?
  2. same-site的变化是什么,对我们的业务有什么影响?
  3. 为什么有了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

其余的属性还有这些:

  1. path:指定cookie未来使用时,可以被携带到合法域名的哪些URI。和domain很像,也只能设置为当前路径的父级路径或其本身,设置值的所有子路径都可以访问。
  2. 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
  1. secure:只能在HTTPS环境中被下发以及携带
  2. http-only:禁止客户端脚本通过 document.cookie 获取 cookie,避免 XSS 攻击。
  3. 还有下面会重点讲解的same-site和same-party

Cookie携带

上面提到,cookie的domain字段很关键,它规定请求哪些域名才会携带,注意,这里指的是请求目的地的域名。

举个例子,首先我通过响应头在浏览器中设置了一个cookie,domain是.a.com

set-cookie: id=nian; domain=.a.com;

现在有三个请求:

  1. 网页www.a.com/index.html的前端页面,去请求接口www.b.com/api
  2. 网页www.b.com/index.html的前端页面,去请求接口www.a.com/api
  3. 网页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的携带,其值有三个nonestrictlax

  1. strict代表完全禁止三方cookie,这是最严格防护,可以避免被CSRF攻击,但缺点也很明显,像天猫、淘宝这种同属一个主体运营的网站不得不重复登录;
  2. none代表完全不做限制,即之前「不认来源,只看目的」的cookie取用原则;
  3. 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>不发送
AJAXaxios.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才是版本答案,有了它,我们可以灵活定义哪些站属于业务意义上的“第一方”,哪些才是我们想要的“第三方”。

如果觉得这篇文章对你有帮助,请点个赞还有关注吧!

你的支持是我创作的动力❤️


前端私教年年
250 声望14 粉丝

鹅厂前端,致力分享说人话的技术文章。