网站怎么记住你已经登录?

发布 · 更新于 · 视频 1:35 · 约 3 分钟读完 · #网络基础#Cookie#Session

章节

  1. 0:00开场
  2. 0:11登录后,两边各自保存
  3. 0:37刷新与换页
  4. 0:58退出登录
  5. 1:19结尾

快捷键:K/空格 播放暂停 · J/L 上/下一章 · ↑/↓ 切换章节

你在 shop.example 登录后按下刷新,结果网站还认得你。可服务器其实不会自己记住你:刷新前后是两次访问,它不会自动把它们连起来。HTTP 规范把这叫作「无状态」。1

跟着一次登录走一遍

1. 登录后,两边各自保存#▶ 从这里看

输入账号密码点登录,服务器核对通过后发回结果。结果里带着一行 Set-Cookie: sid=k3x9q7…,意思是请浏览器把这串编号存下来。3

Cookie 就是浏览器保存的一小段数据,这次存的就是这串编号。

会话 就是服务器保存的登录记录:它记着这串编号对应哪个账号。编号本身是随机生成的,不含密码。

2. 刷新与换页#▶ 从这里看

按刷新,浏览器自动在这次访问里带上 Cookie(Cookie: sid=k3x9q7…),里面还是那串编号。服务器按编号查到会话,认出你是谁,再返回已登录的页面。3

换到订单页也一样:编号自动带上,服务器照样认出你。

3. 退出登录#▶ 从这里看

点退出,服务器先作废这条会话,同一个编号就不能再用来认出你。服务器还让浏览器删掉这条 Cookie,再刷新或换页就不会自动带上它。

所以刷新后还认得你,靠的是浏览器带编号、服务器查会话,这两步缺一不可。

视频里没讲的三件事

HttpOnly:服务器设置 Cookie 时可以加上 HttpOnly,这样网页里的脚本读不到这条 Cookie,但浏览器访问网站时照样会带上它。它能挡住一部分脚本偷编号的情况,却不能让被偷走的编号失效。4

域名范围:Cookie 按域名保存、按域名带回。shop.example 发来的 Cookie,浏览器只在访问 shop.example(以及服务器明确允许的范围)时带上,访问别的网站不会带过去。5

过期时间:服务器可以用 Expires 或 Max-Age 指定 Cookie 存到什么时候;不指定的话,它通常在关闭浏览器后就被清掉。服务器那边的会话另有自己的期限,两边各管各的。退出时常见的写法,是让这条 Cookie 立刻过期,浏览器就会删掉它。6

想一想

只删浏览器里的 Cookie,服务器的会话还有效。有人拿着旧编号,还能被认出来吗?欢迎在评论区说说你的判断。

下期:网站离你那么远,为什么还这么快?

参考资料

Footnotes

  1. RFC 9110:HTTP Semantics,IETF,2022-06,§3.3:HTTP 是无状态的,每个请求可以脱离其他请求来理解。 ↩

  2. RFC 2606:Reserved Top Level DNS Names,IETF,1999-06,.example 留作示例用(§2)。 ↩

  3. RFC 6265:HTTP State Management Mechanism,IETF,2011-04,Set-Cookie(§4.1)、Cookie 请求头(§4.2)。 ↩ ↩2

  4. RFC 6265 §4.1.2.6 The HttpOnly Attribute,HttpOnly 限制非 HTTP 方式(如脚本)读取 Cookie。 ↩

  5. RFC 6265 §4.1.2.3 The Domain Attribute,Cookie 按域名带回的范围;另见 §5.4。 ↩

  6. RFC 6265 §4.1.2.1–4.1.2.2 Expires / Max-Age,Cookie 的过期时间;未设置时为会话 Cookie,当前会话结束时清除,何时结束由浏览器决定。 ↩

幕后

这部片子完全由代码生成。