Cookie、Local Storage 与 IndexedDB:会话究竟是什么

登录会向三个不同的位置写入数据。弄清各自的作用,就能理解为什么会话能挺过某些操作、又会在另一些操作中失效,以及为什么同步配置文件必须把三者都带上。
“已登录”感觉像是一件事。实际上它至少是三件事,存放在三个不同的地方,生命周期也各不相同,而这些差异解释了人们在机器之间迁移会话时遇到的大多数令人困惑的现象。
Cookie
小型键值对,会随每个发往设置它的网站的请求自动发送。会话令牌通常就存放在这里。
- 作用范围限定于域名和路径,并带有过期日期。
- `Secure` Cookie 只通过 HTTPS 发送;`HttpOnly` Cookie 对页面 JavaScript 不可见。
- 会话 Cookie 没有过期时间,旨在浏览器关闭时消失。
Cookie 是三者中最小的,也是承重最多的。丢了它们,你就退出登录了。
Local Storage 与 Session Storage
字符串键值存储,由页面 JavaScript 读写,按来源(origin)划分作用范围。它永远不会随请求发送,页面必须主动去读取。
应用会把偏好设置、缓存的个人资料、功能开关,通常还有刷新令牌保存在这里。Local Storage 会一直保留到被清除;Session Storage 只在标签页存续期间有效。
IndexedDB
浏览器里一个真正的数据库:结构化记录、索引、事务。现代 Web 应用把任何体量较大的内容放在这里:缓存的消息历史、离线队列、端到端加密功能的加密密钥。
这对配置文件意味着什么
它让“隔离”有了精确的含义。当这三者都相互独立,再加上缓存和扩展状态,两个配置文件才算被隔离。只隔离 Cookie 却共用 IndexedDB 的工具,只隔离了问题中最容易的那三分之一。
它也设定了在机器之间迁移配置文件的标准。只携带 Cookie,复现的只是会话的外形,而没有其实质。
| 存储 | 写入者 | 通常存放 |
|---|---|---|
| Cookie | 服务器和页面脚本 | 会话令牌、偏好设置、跟踪标识符 |
| Local Storage | 页面脚本 | 刷新令牌、界面状态、缓存的个人资料 |
| Session Storage | 页面脚本 | 各标签页的状态,标签页关闭时丢弃 |
| IndexedDB | 页面脚本 | 缓存数据、离线队列、加密密钥 |
在你自己的机器之间迁移会话
PowerOps 会在配置文件关闭时捕获 Cookie、Local Storage 和 IndexedDB,并在它于别处打开时恢复它们。每一类都有开关,可针对整个工作区或单个配置文件设置,因此你可以精确地迁移你想迁移的部分。
关于其工作方式,有两点值得了解:
- 快照在其来源的机器上用属于工作区的密钥加密,并在打开该配置文件的机器上解密。这不是端到端加密:服务会保留该密钥的一份副本,好让你的其他电脑能够接收它。
- 一个配置文件同一时间只在一台机器上打开。打开期间它持有一个租约,其他设备会被告知是哪台设备持有它,而不是被允许把会话分叉成两份相互分歧的副本。
第二点是有意设置的限制。两台机器各自独立编辑同一个会话,会产生两个各只有一半有效的会话,而且往往两边的账号都会被登出。Cookie 存储区没有办法解决合并冲突。
实际的结论
要关闭配置文件,而不是强行终止它们。关闭时的写出,是会话可迁移的关键,也是这份清单上成本最低的习惯。

