HTTP 天生健忘(无状态),Cookie 和会话是给它装的记性——Cookie 把小纸条存在你浏览器里,会话把底账存在服务器里,两边用同一个 SessionID 对上号。
上游:网络 4.7 · Cookie 已讲过报文细节;本篇补全「Cookie+会话」这对搭档与安全边界。下游:6-5 的动态网站靠它区分用户,6-19 的 XSS/CSRF 攻击主要就打这里。
一、为什么需要记性
HTTP 每个请求都是独立的——服务器处理完就忘。可现实需求全靠记性:登录状态、购物车、阅读进度。解法两步:
1. 第一次见面发凭证:服务器在响应里塞一句 Set-Cookie: sessionid=abc123,浏览器存下来。
2. 之后每次自报家门:浏览器对该站点的每个请求自动带上 Cookie: sessionid=abc123。
# Python 标准库视角:Set-Cookie 长什么样
from http.cookies import SimpleCookie
c = SimpleCookie()
c["sessionid"] = "abc123"
c["sessionid"]["max-age"] = 3600 # 1 小时后过期
c["sessionid"]["httponly"] = True # 禁止 JS 读取(防 6-19 的 XSS 偷凭证)
print(c.output())
# Set-Cookie: sessionid=abc123; Max-Age=3600; HttpOnly
二、Cookie:浏览器里的小纸条
- 本质:键值对+属性(域、路径、过期时间、安全标志)。
- 分类:会话 Cookie(不设过期、关浏览器即删)vs 持久 Cookie(设了
Max-Age/Expires)。 - 边界:每个域名几十条、每条几 KB 的量级——只能存小凭证,不能当数据库。
- 隐私争议:第三方 Cookie 能跨站追踪你的浏览足迹,是「禁止跟踪」大战的主角;现代浏览器已陆续封杀第三方 Cookie。
三、会话(Session):服务器里的底账
敏感数据(用户名、权限、购物车)不进 Cookie,存服务器的会话存储里;Cookie 里只放一把钥匙 SessionID:
浏览器 Cookie: sessionid=abc123 → 服务器会话表:
abc123 → {user: 波仔, cart: [键盘×2]}
- 服务器重启/会话过期,底账清空——所以有「登录过期请重新登录」。
- SessionID 一旦泄露(被偷、被猜、被固定),别人就能冒充你——会话安全的全部重心在这串随机数上:足够长、足够随机、HTTPS 传输、HttpOnly 防 JS 偷。
Cookie 与 Token(JWT):教材时代主流是「服务器存底账」的 Session;如今前后端分离流行把凭证本身(签名过的 Token)发给客户端保存——服务器不用存底账,但无法单方面作废。两条路线至今并存。
动手 Demo:自己当一次服务器,发 Cookie
# 用 Python 内置 HTTP 服务器发 Cookie(保存为 demo_cookie.py 运行)
from http.server import BaseHTTPRequestHandler, HTTPServer
class H(BaseHTTPRequestHandler):
def do_GET(self):
if "sessionid=" in self.headers.get("Cookie", ""):
body = "欢迎回来,老朋友!".encode()
self.send_response(200)
self.end_headers()
else:
body = "第一次来?送你一张 Cookie。".encode()
self.send_response(200)
self.send_header("Set-Cookie", "sessionid=xyz789; HttpOnly")
self.end_headers()
self.wfile.write(body)
HTTPServer(("127.0.0.1", 8000), H).serve_forever()
看到什么算成功:浏览器开 http://127.0.0.1:8000 显示「第一次来?」,刷新后变成「欢迎回来,老朋友!」——F12 → 应用(Application)→ Cookie 里能看到 sessionid=xyz789。
读结果:第二次请求浏览器自动带上了 Cookie,服务器据此认出了你——整套登录机制的最小原型就这十行。
30 秒实验
F12 → 应用(Application)→ Cookie → 选任意网站看一眼;再在控制台跑 document.cookie——若返回空,说明该站 Cookie 设了 HttpOnly(JS 读不到,防偷)。数一数自己常逛的网站给你埋了多少条小纸条。
常见误区
- 「Cookie 是病毒/垃圾」——Cookie 本身是文本凭证不是程序;恶心的是第三方追踪 Cookie,功能 Cookie 是登录的命根子,全删了处处要重新登录。
- 「会话数据存在 Cookie 里」——恰恰相反:Cookie 只放 SessionID 钥匙,底账在服务器;把用户名密码塞 Cookie 是重大事故。
- 「关闭浏览器登录就过期=会话在浏览器里」——会话底账一直在服务器;浏览器关闭只是丢了会话 Cookie 这把钥匙(或钥匙过期),服务器那边的底账等超时自己清。
自测三问(点击展开)
1. **HTTP 无状态是什么意思?** 答:每个请求独立处理,服务器不记得请求之间的关联。 2. **Cookie 和 Session 各存什么、在哪存?** 答:Cookie 存 SessionID(浏览器);Session 存用户状态底账(服务器);两边靠 SessionID 对号。 3. **SessionID 被偷会怎样?怎么防?** 答:被偷=被冒充;防法=足够随机+HTTPS+HttpOnly+及时过期。- ☑ 6-4 完成 —— 健忘协议装记性:Cookie 小纸条+会话底账
- ☐ 下一节 6-5 静态Web网站、动态Web网站、CGI
相关笔记
- 网络 4.7 · Cookie —— 报文级细节
- 安全漏洞 —— XSS 偷 Cookie 的攻击面
- ⌨️ 编程原理 · 索引 —— 全课路线图