日前 Chrome 工程师 Mike West 发表了一篇文章提议改造 Cookie 标准,以强化 HTTP 状态管理。
Mike 分析了目前 Cookie 存在的几个方面的问题,包括很难安全使用、浪费用户资源,以及隐私问题,通过它可以以令人惊讶的方式跟踪用户在网络上的活动。
关于浪费用户资源,Mike 解释,服务器可以为一个注册域名存储大量 Cookie,并且很多 Cookie 可以通过 HTTP 请求发送。例如 Chrome 允许为每一个域名存储大约 180 个 Cookie,相当于约 724kB 数据。在众多 Cookie 中,其请求头大小的中位数是 409 字节,但是其中却有 90% 有 1589 字节,95% 占了 2549 字节,99% 甚至达到了 4601 字节,另外有约 0.1% 的 Cookie 头非常大,超过了 10kB。如此滥用,效率低下。
隐私方面,众所周知 Cookie 可以用于身份验证,但它同时也可以用来悄悄跟踪用户的相关信息。
而关于安全使用的难处,Mike 列出了几条在开发中安全使用 Cookie 遇到的问题:
Mike 认为,一方面 Cookie 采用的缓解安全问题的属性很差,Cookie 根本不符合我们决定对其它类型的 Web 可访问数据强制执行的安全边界。它们在给定的可注册域中流过源,它们忽略端口和方案,这意味着它们可以被网络攻击者轻易伪造,并且它们可以缩小到特定路径,这些特征使得它们难以推理,并制定激励措施来削弱平台其它部分的同源策略。
Mike 给出了一套新方案,他解释,用户代理可以通过为用户访问的每个安全源生成唯一的 256 位值来控制它代表用户表示的 HTTP 状态,此 Token 可以作为结构化 HTTP 请求头传递到源:
Sec-HTTP-State:token = * J6BRKagRIECKdpbDLxtlNzmjKo8MXTjyMomIwMFMonM *
此标识符或多或少类似于客户端控制的 Cookie,但有一些值得注意的区别:
在些基础上,将为开发人员提供一些可通过 Sec-HTTP-State-Options HTTP 响应头触发的控制点,有如下选项:
1、某些服务器需要跨站点访问其 Token,其它服务器可能希望将交付范围缩小到同源请求,服务器可以指定任一选项:
Sec-HTTP-State-Options: ..., delivery=cross-site, ...
或者:
Sec-HTTP-State-Options: ..., delivery=same-origin, ...
2、某些服务器希望限制 Token 的生命周期,可以允许它们设置 TTL(以秒为单位):
Sec-HTTP-State-Options: ..., ttl=3600, ...
时间到期后,Token 的值将自动重置。同时服务器也可能希望明确触发 Token 的重置行为(例如,在注销时),这可以通过设置 TTL 为 0 来实现:
Sec-HTTP-State-Options: ..., ttl=0, ...
在任何一种情况下,都可以向当前运行的页面通知用户的状态变化,以便执行清理操作。当发生重置时,用户代理可以将消息发送到名为 http-state-reset 的源的 BroadcastChannel(并且可能唤醒源的 Service Worker 以响应用户驱动的重置):
let resetChannel = new BroadcastChannel('http-state-reset')); resetChannel.onmessage = e => { /* Do exciting cleanup here. */ };
3、对于某些服务器,客户端生成的 Token 足以维持状态,它们可以将其视为不透明的会话标识符,并将用户的状态绑定到服务器端。其它服务器需要额外的保证,他们可以信任 Token 的出处,为此,服务器可以生成唯一密钥,将其与服务器上的会话标识符相关联,并通过 HTTP 响应头将其传递给客户端:
Sec-HTTP-State-Options: ..., key=*ZH0GxtBMWA...nJudhZ8dtz*, ...
客户端将存储该密钥,并使用它来生成某些数据集的签名,从而降低 Token 被捕获的风险:
Sec-HTTP-State: token=*J6BRKa...MonM*, sig=*(HMAC-SHA265(key, token+metadata))*
Mike 同时也表示,该方案并不是一个完全与 Cookie 不同的新东西,并不是要在目前替换掉 Cookie,虽然弃用 Cookie 是应该的,但是当下该方案只是提出了一种在 Cookie 同时存在的情况下也能发挥作用的补充机制。
领取专属 10元无门槛券
私享最新 技术干货