Cookie、Session、JWT 三者的比较(最清晰的结构版)
1. 它们分别是什么?
| 技术 | 本质 | 存储位置 | 主要用途 |
|---|---|---|---|
| Cookie | 浏览器存储机制 | 浏览器 | 存小数据、携带会话 ID |
| Session | 服务端会话机制 | 服务器(内存/Redis) | 保存用户状态 |
| JWT | 无状态 Token | 客户端(Cookie/Storage) | 分布式认证、前后端分离 |
2. 工作方式对比(面试官最爱听的部分)
Cookie
-
浏览器自动携带到同域请求中
-
可以设置
HttpOnly、Secure、SameSite -
不负责认证,只是一个存储容器
你可以强调一句:
Cookie 本身不做认证,只是用来存 session_id 或 JWT。
Cookie 的三个关键安全属性
1. HttpOnly
作用:防止 JavaScript 读取 Cookie,抵御 XSS 攻击。
-
设置后,前端 JS 无法通过
document.cookie获取 Cookie -
但浏览器仍会自动携带 Cookie 发请求
-
常用于存放 JWT、SessionID 等敏感信息
示例:
Set-Cookie: token=xxx; HttpOnly
你可以这样总结:
HttpOnly 主要防止 XSS 读取 Cookie,不让攻击者通过脚本窃取 Token。
2. Secure
作用:Cookie 只能在 HTTPS 下传输,防止中间人攻击(MITM)。
-
只有 HTTPS 才会携带 Cookie
-
HTTP 请求不会带 Cookie
-
防止 Token 在明文传输中被抓包
示例:
Set-Cookie: token=xxx; Secure
你可以这样说:
Secure 确保 Cookie 只在 HTTPS 下发送,避免 Token 在明文网络中被窃听。
3. SameSite
作用:限制跨站请求携带 Cookie,防止 CSRF。
它有三个值:
① SameSite=Strict(最安全)
-
完全禁止跨站携带 Cookie
-
即使从其他网站点击链接跳转过来也不会带 Cookie
② SameSite=Lax(默认)
-
跨站 GET 请求可以带 Cookie(比如点击链接)
-
跨站 POST、PUT、DELETE 不会带 Cookie
-
安全性与可用性平衡
③ SameSite=None(允许跨站)
-
必须配合
Secure -
常用于前后端分离、跨域场景
示例:
Set-Cookie: token=xxx; SameSite=Lax
你可以这样总结:
SameSite 是防 CSRF 的关键,通过限制跨站请求是否能携带 Cookie 来阻断攻击。
Session(有状态)
-
登录后,后端生成
session_id -
session_id写入 Cookie -
用户状态(user_id、权限等)存 服务器内存/Redis
-
每次请求:浏览器带上
session_id→ 后端查 Session
特点:
-
服务器有状态
-
多机部署需要 Session 共享(Redis)
-
扩展性一般
适合:
-
传统 MVC
-
小规模系统
-
不需要多端统一认证
JWT(无状态)
-
登录后,后端生成 Token(Header + Payload + Signature)
-
Token 存在客户端(推荐 HttpOnly Cookie)
-
每次请求:浏览器带 Token → 后端验证签名即可
特点:
-
服务器无状态
-
不需要 Session 共享
-
多端(Web、App、小程序)统一认证
-
适合分布式、微服务
缺点:
-
Token 无法主动失效(需要 Redis 黑名单)
-
Payload 明文,不要放敏感信息
PyJWT 的组成是什么?(标准回答)
你可以这样说:
PyJWT 生成的 JWT 由三部分组成:Header、Payload、Signature。 三段之间用
.分隔,分别负责算法声明、业务数据载荷和签名校验。
然后你展开讲:
1. Header(头部)
说明 使用什么算法 来签名 Token。
典型结构:
{
"alg": "HS256",
"typ": "JWT"
}
-
alg:签名算法(HS256、RS256 等) -
typ:类型,固定为 JWT
面试官听到你提到 HS256 vs RS256 会觉得你很专业。
2. Payload(载荷)
存放 业务数据 + 标准声明(Claims)。
常见字段:
| 字段 | 含义 |
|---|---|
sub | 用户 ID(Subject) |
exp | 过期时间(Expiration) |
iat | 签发时间(Issued At) |
nbf | 生效时间(Not Before) |
iss | 签发者(Issuer) |
role | 用户角色(自定义) |
permissions | 权限列表(自定义) |
你可以补一句:
Payload 是明文的,不要放敏感信息,比如密码、手机号等。
这句话会让你显得很懂安全。
3. Signature(签名)
用于验证 Token 是否被篡改。
计算方式:
Signature=HMACSHA256(base64(header)+"."+base64(payload),secret)
如果是 RS256:
Signature=RSA_SHA256(header.payload,private_key)
你可以顺便提一句:
HS256 是对称加密(同一个 secret),RS256 是非对称加密(公钥/私钥)。
面试官会觉得你对算法也很熟。
PyJWT 生成 Token 的示例(你可以顺便讲)
import jwt
import datetime
payload = {
"sub": user_id,
"role": "admin",
"exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1),
"iat": datetime.datetime.utcnow()
}
token = jwt.encode(payload, "SECRET_KEY", algorithm="HS256")
解析:
jwt.decode(token, "SECRET_KEY", algorithms=["HS256"])
你可以这样总结(面试官最爱听的版本)
PyJWT 生成的 JWT 由三部分组成:Header、Payload 和 Signature。 Header 指定算法,Payload 存放用户信息和过期时间,Signature 用于防篡改。 这三部分分别 Base64URL 编码后用
.拼接,后端通过相同算法和密钥验证签名是否一致,从而判断 Token 是否有效。
3. 安全性对比(面试官会重点问)
| 项目 | Cookie | Session | JWT |
|---|---|---|---|
| 防 XSS | ❌(除非 HttpOnly) | ✔️ | ✔️(放 HttpOnly Cookie) |
| 防 CSRF | ❌(需 SameSite/CSRF Token) | ❌ | ❌(需 SameSite/双重 Cookie) |
| 服务端存储 | ❌ | ✔️ | ❌ |
| 可主动失效 | ✔️ | ✔️ | ❌(需黑名单) |
| 可扩展性 | 中 | 差 | 强 |
你可以补一句非常加分的话:
JWT 的安全性不是比 Session 强,而是适合分布式架构。真正的安全取决于 HttpOnly、SameSite、短期 Token、Refresh Token、黑名单等策略。
4. 使用场景对比(面试官最喜欢听的)
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 传统网站(Django 模板) | Session | 简单、稳定 |
| 前后端分离 | JWT + HttpOnly Cookie | 无状态、跨域友好 |
| 多端统一登录(Web + App) | JWT | 不依赖浏览器 Cookie |
| 分布式/微服务 | JWT | 不需要 Session 共享 |
| 高安全性系统 | Session 或 JWT + 黑名单 | 可控性强 |
5. 你可以这样总结(面试官会点头的版本)
Cookie 是浏览器的存储容器,Session 是服务端有状态会话,JWT 是无状态 Token。 Session 适合传统架构,但扩展性差;JWT 更适合前后端分离、多端登录和分布式系统。 我们通常把 JWT 放在 HttpOnly Cookie 中,结合短期 Access Token、长期 Refresh Token 和 Redis 黑名单,实现安全且可扩展的认证体系。
这段话你背下来,面试官会觉得你对认证体系非常熟。

被折叠的 条评论
为什么被折叠?



