天天看点

谷歌 Chrome: Cookie 访问方式大调整

作者:Echa攻城狮
谷歌 Chrome: Cookie 访问方式大调整

大家好,我是Echa。

最近小编一直在关注谷歌官方浏览器 Chrome,就在前段时间谷歌 Chrome 团队正式发布了六年磨一剑的WebGPU,借助现代 GPU 的计算能力来加速图形和计算并且允许在 Web 上进行高性能 3D 图形和数据并行计算。当时业界圈内一片哗然——重磅!谷歌正式发布 WebGPU

这次谷歌 Chrome 又接二连三的发布了Chrome 113、114 两个版本,都有提到关于 Cookie 的访问方式变化:

  • Chrome 113:Cookie 第一方集(First-Party Sets)进入稳定版本;
  • Chrome 114:Cookie 独立分区(CHIPS)默认对所有浏览器启用;
谷歌 Chrome: Cookie 访问方式大调整

Chrome 113 First-Party Sets

谷歌 Chrome: Cookie 访问方式大调整

Chrome 114 :Cookie 独立分区(CHIPS)

为啥小编特意截上面两张Chrome 官方的图出来,因为这两个都是针对 Cookie 访问方式的大调整,为的就是应对即将来临的三方 Cookie 全面弃用。Chrome 在两年前就已经计划全面弃用方 Cookie 了,因为这个变化对现在的网站影响太大了,如果直接弃用,可能会导致大量网站的正常功能无法正常使用。

另外对 Google 本身的广告业务也有非常大的影响,所以 Chrome 不得不一拖再拖,为的就是能够推出一套对现有的业务影响不是很大,能够保障用户平稳迁移,又能保护用户隐私的方案。

目前看来,随着 Cookie 第一方集、Cookie 独立分区两项能力的稳定推出,全面禁用三方 Cookie 的那一天似乎不远了,这两项改动确实能够解决一大部分正常使用三方 Cookie 的业务场景,但是 Cookie 的读取方式可能要有大调整了。

今天小编就带着大家来提前解读一下这两项关于 Cookie 的大调整,大家也要提前做好迁移和应对策略,保障未来禁用三方 Cookie 之后网站能够避免受到影响。

首先了解Cookie如何产生、Cookie 分类、Cookie用途、Cookie生命周期

Cookie的生命周期有两种,一种是整个会话的,一种是永久的。也就是说,一种是临时性的Cookie,用户关掉浏览器,这个Cookie也就失效了。一种是永久的Cookie,可以持续存在的。一般网站分析工具 判断Unique Visitor使用的是后者。

千言万语,不如一张完整的图讲解:

谷歌 Chrome: Cookie 访问方式大调整
谷歌 Chrome: Cookie 访问方式大调整
谷歌 Chrome: Cookie 访问方式大调整

第一方和第三方Cookie的区别

Cookie 是属于一方 Cookie、还是三方 Cookie,只取决于两个要素:

  • Cookie 是被哪个域名种的
  • Cookie 是在哪个网站上种的

第一方Cookie和第三方Cookie,都是网站在客户端上存放的一小块数据。他们都由某个域存放,只能被这个域访问。他们的区别其实并不是技术上的区别,而是使用方式上的区别。

比如,访问www.douyin.com这个网站,这个网站通过set-cookie 这个 Header设置了一个Cookie,这个Cookie也只能被www.douyin.com 这个域下的网页读取,这就是第一方Cookie。

谷歌 Chrome: Cookie 访问方式大调整

如果还是访问www.douyin.com这个网站,网页里有用到bytedance.com网站的一张图片,浏览器在向 bytedance.com请求图片的时候,bytedance.com通过set-cookie 这个 Header 设置了一个Cookie,那这个Cookie只能被bytedance.com这个域访问,反而不能被 www.douyin.com这个域访问,因为对我们来说,我们实际是在访问www.douyin.com这个网站被设置了一个bytedance.com个域下的Cookie,所以叫第三方Cookie。

谷歌 Chrome: Cookie 访问方式大调整

第一方Cookie的优势和应用

第一方Cookie的最大优势是接受率高。一般主流的浏览器的都会有隐私的设置,可以让用户设置是否接受Cookie,接受哪些Cookie。

除了 完全不接受Cookie这个设置以外,其他情况下,第一方Cookie都是会被用户接受的(不接受的话,是没办法把那小块数据保存下来的)。

所以,如果没有特殊要求,使用第一方Cookie会比第三方Cookie,我们通过分析工具得到的数据会更准确。

三方Cookie的优势和应用

第三方Cookie的接受率不如第一方Cookie(不过主流的浏览器默认的设置下也接受带P3P协议的第三方Cookie,我的经验是接受率能达到90%,甚至95%以上),但在某些特定情况下可以实现第一方Cookie无法实现的功能。

比如,当我们有多个域名的网站需要跟踪,我们希望了解到用户 点击某个广告到达域名A下的网页,然后可能浏览了不论那个域名下的页面,最后在域名B下的网页完成注册的情况。广告可以在域名A下的网页被跟踪到,而注册 可以在域名B下的网页跟踪到。

如果我们使用第一方Cookie,会为域名A建立一个Cookie,为域名B再建立一个Cookie,他们可以关联各自域名 下网页上的行为,但是无法关联起来。而使用第三方Cookie,那么无论多少个域,都只有一个Cookie,一个属于第三方域的Cookie,网站下所有域都能共享这个Cookie,那么所有的行为都能被关联起来分析。

三方 Cookie 有啥问题?

我们的网站不可能只调用同站的域名的接口,调用其他域名的接口再正常不过了,所以有三方 Cookie 也是很正常的,我们也通过三方 Cookie 做了很多正常的需求,比如日志打点、单点登录、广告转化分析等等。那为什么要禁用呢?主要还是因为用户隐私的问题。

谷歌 Chrome: Cookie 访问方式大调整

比如我们现在正在抖音上刷视频,但是抖音上往往会加载很多三方广告商的请求,这些三方广告商就可以通过三方 Cookie 来记录一些用户的行为。然后下次你逛淘宝的时候,也可能再次加载到这个广告商,因为这时三方广告已经通过三方 Cookie 记录了你的很多用户行为,已经知道了你喜欢什么东西,所以你就会收到一些精准的广告推送,无形之中你的隐私已经泄漏出去了。

在海外,用户隐私可是相当ZZ正确的事,所以 Safira、Firefox 两大浏览器已经迫于压力禁用了三方 Cookie,也就是说,如果你在这两个浏览器上去访问 www.douyin.com 这个网站,那么再发送 bytedance.com 这个域名的请求是种不上 Cookie 的。

目前就剩下 Chrome 还在苦苦支撑了,毕竟 Chrome 现在的浏览器市场份额是最大的,而且直接禁用对它的老板 Google 的广告业务影响也非常大。所以 Chrome 需要等待一个大家都可接受的替代方案出来之后再禁用。

为了增加网络隐私,浏览器供应商正在计划或已经对跨站点跟踪进行限制。这包括逐步取消对第三方cookie的支持,即向顶级文档网站以外的网站发送请求的cookie,因为此类cookie使服务器能够跟踪用户在不同顶级网站上的行为。

谷歌 Chrome: Cookie 访问方式大调整
谷歌 Chrome: Cookie 访问方式大调整

在cookie之前:浏览器访问green.com,它有一个嵌入的red.com框架,可以设置cookie。当浏览器导航到blue.com时,red.com框架可以访问green.com上设置的cookie。

两个可能遇到问题的场景

对于我们普通开发者来说,其实还是有很多场景可能会受到影响的,我们也必须在禁用之前作出相应的改变,比如下面两个场景。

三方 iframe Cookie

第一个场景是我们需要和嵌入的三方 iframe 共享状态。假如我们现在开发了一个通用的聊天服务,它的域名是 support.chat.example,我们有很多业务网站(比如 retail.example) 希望用 iframe 的方式嵌入这个聊天框。这个嵌入式的聊天服务可能会依赖 Cookie 来保存用户的交互历史记录。因为我们嵌入的 iframe 域名和当前的网站是夸站的,所以 iframe 种下的 Cookie 就属于三方 Cookie。

谷歌 Chrome: Cookie 访问方式大调整

假如现在没有了设置跨站点三方 Cookie 的能力,那我们的聊天服务 support.chat.example 可能需要更依赖父级网站 retail.example 主动传递给他们第一方会话的一些标识符。因为这种聊天服务往往都是通用的,所以相应的每个嵌入 support.chat.example 聊天服务的网站都需要额外的设置来传递状态,这大大增加了开发和接入成本。

或者,我们也可以允许聊天服务 support.chat.example 请求我们的网站 retail.example 页面上的 JavaScript。但是这又引入了非常大的安全风险,也不是个靠谱的方法。类似可能遇到的场景还包括:

  • 三方地图服务
  • 子资源 CDN 负载均衡
  • Headless CMS 提供商
  • 不信任的用户内容的沙盒域名
  • 三方嵌入式广告

三方站点 Cookie

另外还有一个场景,根据域名的不同来定义 Cookie 属于第三方有点太狭隘了,毕竟一个公司不可能只有一个域名:

谷歌 Chrome: Cookie 访问方式大调整

比如上面我们提到的 www.douyin.com 和 www.bytedance.com ,虽然域名不一样,种的 Cookie 也叫做三方 Cookie,但是明眼人都能看出来,抖音就是字节的,这俩域名就是一家的。

谷歌 Chrome: Cookie 访问方式大调整

如果禁用了三方 Cookie ,那这种正常的在一家公司不同域名下共享 Cookie 的能力也就不能用了,这给正常的业务需求会带来很大的影响,一个常见的场景就是单点登录,我们往往在登陆一家公司的不同网站的时候只需要登录一次,这是因为用户的个人信息存储在了一个公共的登录服务的 Cookie 上,禁用了三方 Cookie,那登录信息也就无法共享了。下面我们来看看如何解决以上的两个问题。

Cookie 独立分区(CHIPS)

首先我们来看 Chrome 114 默认对所有用户启用的 Cookie 独立分区(CHIPS),这就是用来解决三方 iframe 共享状态的问题的。

如何解决问题?

具有独立分区状态的 Cookie (CHIPS) ,它允许开发者将 Cookie 选择到“分区”存储中,每个顶级站点都有单独的 Cookie jar。

Chrome 官方是这样描述它的:CHIPS 是帮助服务顺利过渡到没有第三方 Cookie 的未来的重要一步。

CHIPS 引入了一个新的 Cookie 属性:Partitioned ,它可以让顶级上下文分决定哪些 Cookie 进行分区。

举个例子,假如我们在站点 A 中通过 iframe 嵌入了一个站点 C,正常情况下如果三方 Cookie 被禁用后,C 是无法在 A 站点访问到它的 Cookie 的。

如果 C 在它的 Cookie 上指定了 Partitioned 属性,这个 Cookie 将保存在一个特殊的分区 jar 中。它只会在站点 A 中通过 iframe 嵌入站点 C 时才会生效,浏览器会判定只会在顶级站点为 A 时才发送该 Cookie。

谷歌 Chrome: Cookie 访问方式大调整

当用户访问一个新站点时,例如站点 B,如果也它通过 iframe 嵌入了站点 C,这时在站点 B 下的站点 C 是无法访问到之前在 A 下面设置的那个 Cookie 的。

如果用户直接访问站点 C ,一样也是访问不到这个 Cookie 的。

谷歌 Chrome: Cookie 访问方式大调整

这样就在保障用户隐私的情况下解决了三方 iframe Cookie 共享的问题。

如何使用?

实施方式也非常简单,就像上面说的,想要在当前网站上保留需要共享的三方 Cookie ,只需要在种这个 Cookie 的时候添加一个 Partitioned 属性,另外还有个前提是 Cookie 必须具有 Secure 属性:

Set-Cookie: name=ConardLi; SameSite=None; Secure; Path=/; Partitioned;           

实现细节

Partitioned 属性实际上是改变了 Cookie 存储分区的机制,让分区更加严格了,还是上面的例子,我们将一个 https://support.chat.example iframe 嵌入在页面 https://retail.example 上,在启用 Partitioned 之前,Cookie 分区的唯一标识是:support.chat.example ,而启用了Partitioned之后,分区的唯一标识变成了 ("https", "retail.example") + support.chat.example。

谷歌 Chrome: Cookie 访问方式大调整

Firefox 在它的 ETP 严格模式和隐私浏览模式下默认对所有第三方 cookie 进行了分区,所以所有的跨站 cookie 都会默认按照顶级站点进行分区。但是,在没有第三方选择加入的情况下对 cookie 进行分区可能会导致一些意外的问题,因为在某些特定场景下可能也会用到未分区的第三方 cookie。

Safari 之前也曾尝试过一些 Cookie 分区的机制,但最终还是放弃了,目前完全阻止了三方 Cookie,理由之一是开发者可能会感到困惑。。不过目前好像又开始做一些 Cookie 分区的实验了。

目前我觉得 Chrome 提供的这种启发式 Cookie 分区的思路还挺好用的,既解决了跨站跟踪的问题,而且也能在一定程度上满足用户需求,希望其他浏览器也借鉴一下吧。

Cookie 第一方集(First-Party Sets)

上面我们解决了三方 iframe 状态共享的问题,下面我们提到的 Cookie First-Party Sets 则是用来解决自定义 Cookie 集合的问题,也就是说提供了一种选择性的把一些 Cookie 从三方变为一方的方式。

如何解决问题?

前面我们提到了,很多组织或公司都会有多个域名,所以只用域名的不同来区分 Cookie 属于第一方还是第三方这种方式太严格了。

谷歌 Chrome: Cookie 访问方式大调整

First-Party Sets 相当于给了网站开发者一个机会,有一些 Cookie 虽然根据域名的划分是第三方的,但是你可以自己选择指定一部分 Cookie 把它们放在一个集合里,在这个集合里的三方 Cookie 都可以按照一种特殊的形式来读取到。

谷歌 Chrome: Cookie 访问方式大调整

换个角度讲,douyin.com、bytedance.com 这两个域名虽然是属于同一个组织,但是 Chrome 不知道,你可以通过把它们放到一个集合里来告诉 Chrome 这些不同的域名属于同一个组织。

如何使用?

根据上面的解决问题的思路,想要实现 First-Party Sets 就需要两步:

  • 第一步:把想要共享 Cookie 的不同域名放到一个集合里,然后提交给 Chrome;
  • 第二步:使用 Chrome 提供的特殊的方式来读取这些域名集合下共享的 Cookie;

在早期的提案中,为 Cookie 新增了一个 samePaty 属性,你可以通过这个属性来告诉浏览器哪些 Cookie 是需要三方共享的,然后需要把共享的域名集合放到网站的部署目录下。

但是,这种方式的限制有点过于宽松了,网站可以很轻松的再次实现三方 Cookie 共享,共享的策略也不够透明,所以 Chrome 决定弃用了这种方案,转而实现了一种更复杂的方式。

首先你需要给出一份 JSON 文件,在这个文件里声明哪些域名是需要共享 Cookie 的,然后你需要把这个 JSON 文件通过 Pull Request 提交到 Chrome 提供的一个 Github 仓库中:https://github.com/GoogleChrome/first-party-sets

而且要求 JSON 文件的格式必须符合规范,下面是一个例子:

{
  "primary": "https://primary.com",
  "associatedSites": ["https://associate1.com", "https://associate2.com", "https://associate3.com", "https://associate4.com"],
  "serviceSites": ["https://servicesite1.com"],
  "rationaleBySite": {
    "https://associate1.com": "An explanation of how you clearly present the affiliation across domains to users and why users would expect your domains to be affiliated",
    "https://associate2.com": "An explanation of how you clearly present the affiliation across domains to users and why users would expect your domains to be affiliated",
    "https://associate3.com": "An explanation of how you clearly present the affiliation across domains to users and why users would expect your domains to be affiliated",
    "https://serviceSite1.com": "An explanation of how each domain in this subset supports functionality or security needs."
  },

  "ccTLDs": {
    "https://associate1.com": ["https://associate1.ca", "https://associate1.co.uk", "https://associate1.de"],
    "https://associate2.com": ["https://associate2.ru", "https://associate2.co.kr", "https://associate2.fr"],
    "https://primary.com": ["https://primary.co.uk"]
  }
}           

在这其中有几个关键的概念:

谷歌 Chrome: Cookie 访问方式大调整
  • ccTLDs 域名:网站可能服务于不同的国家,在每个地区都有一个特定的域名,比如 conardli.cn、conardli.jp、conardli.en 等等;
  • Service 域名:网站可能会使用特定的域名来保证安全性或者提高性能,但是这些不同域名的网站可能也需要共享用户身份。
  • Associated 域名:同一个组织下可能有多个不同的子品牌,对应不同的域名,例如 bytedance.com、douyin.com 就属于这种情况。

提交完 PR 之后,Google 团队会在每个周二的中午 12 点手动 Review 并且合并这些 PR。(这里我也不知道 Chrome 团队是咋想的。。。后面网站多了之后肯定每天都有大量的 PR,这种维护方式真的可行么??)

等到你的 JSON 配置被 Chrome 团队 Merge 后,也不是就代表着你可以随意在这些域名下共享三方 Cookie 了,你还需要用到一个特殊的 Storage Access API(SAA) ,下面是一份演示代码:

https://glitch.com/edit/#!/first-party-sets

我们来拆解一下,首先是判断浏览器是否支持这个 API:

/* 
 * 通过 UA 判断浏览器版本
 */
if (navigator.userAgentData.brands.some(b => { return b.brand === 'Google Chrome' && parseInt(b.version, 10) >= 108 })) {
  // Supported
} else {
  // Not supported
}

/* 
 * 判断 SAA 和 rSAFor API 是否可用
 */
if ('requestStorageAccess' in document) {
  // SAA available
} else {
  // SAA not available
}

if ('requestStorageAccessForOrigin' in document) {
  // rSAFor available
} else {
  // rSAFor not available
}
           

通过 requestStorageAccess 来判断用户是否授予了对三方 Cookie 的访问权限,并且访问所有可以读取到的 Cookie:

if ('requestStorageAccess' in document) {
document.requestStorageAccess().then(
      (res) => { console.log('权限请求通过', res) },
      (err) => { console.log('拒绝', err) }
   );
}
           

通过 requestStorageAccessForOrigin 来读取指定域名下共享的的三方 Cookie:

if ('requestStorageAccessForOrigin' in document) {
document.requestStorageAccessForOrigin('https://first-party-sets.glitch.me');
   location.reload();
} else {
   window.alert('document.requestStorageAccessForOrigin not enabled.');
}
           

最后

一台电脑,一个键盘,尽情挥洒智慧的人生;几行数字,几个字母,认真编写生活的美好;

一 个灵感,一段程序,推动科技进步,促进社会发展。

创作不易,喜欢的老铁们加个关注,点个赞,打个赏,后面会不定期更新干货和技术相关的资讯,速速收藏,谢谢!你们的一个小小举动就是对小编的认可,更是创作的动力。