Backend interview · authentication architecture

Cookie、Session 与 JWT:别背概念,先看凭证到底去了哪里

它们不是三选一的同类产品:Cookie 是浏览器携带数据的机制,Session 是服务端保存会话状态的机制,JWT 是可签名验证的令牌格式。正确选型,要从业务的撤销、终端、部署和安全边界出发。

DEFAULT FOR WEB先用 Cookie + 服务端 Session同站 Web、需要随时强制下线、权限变化必须即时生效时,简单且稳妥。
API / MULTI-CLIENT短 JWT + Refresh TokenApp、开放 API、跨服务身份传递,令牌走 Authorization 头;仍要设计吊销与刷新。
DO NOT CONFUSEJWT 也能放 HttpOnly Cookie存储位置与令牌格式是两件事。放 Cookie 要处理 CSRF;放 JS 可读存储要处理 XSS。
01 / where the state lives

一张图先分清:谁带凭证,谁存状态,谁来验证

登录都从账号密码校验开始;分岔发生在“登录成功后服务器交给客户端什么”和“下一次请求服务器需不需要查状态”。

同一条请求路径,两种会话实现

Cookie / 浏览器Session / 服务端状态JWT / 自包含令牌
浏览器 / 客户端
存放或携带凭证
Authorization: Bearer eyJ…客户端显式放入请求头
HTTP(S)
Session Store用 sid 查 Redis / DB / 内存 → 取用户状态
Token Verifier验签 + 校验 exp / iss / aud → 读声明
认证结果Cookie+Session:服务端状态为准

JWT:签名与有效期为准;要即时失效则另加状态
02 / three different layers

三者不在同一个维度

把它们并列为“认证方案”很容易答偏。先把层次拆开,才能说明为什么 Cookie+Session 常搭配,而 JWT 可以通过请求头或 Cookie 传递。

BROWSER MECHANISM

Cookie

浏览器按域、路径、SameSite、Secure 等规则保存并自动携带的小数据块。

  • 它能装什么?
    Session ID、JWT、偏好设置等。
  • 它不是什么?
    Cookie 本身不等于登录状态,也不等于 Session。
  • 关键边界
    HttpOnly 降低 XSS 读取风险;自动携带意味着要设计 CSRF 防护。
SERVER-SIDE STATE

Session

服务端按会话 ID 保存的登录状态与上下文;存储可以是内存、Redis、数据库等。

  • 客户端拿到什么?
    通常只拿一个无意义的 sid。
  • 它的强项
    删除或变更服务端记录即可立即注销、封禁、刷新权限。
  • 它的代价
    集群要共享状态;高并发需规划存储容量、可用性和查询延迟。
TOKEN FORMAT / RFC 7519

JWT

由 Header.Payload.Signature 组成、可被验签的声明令牌格式;不是“无状态认证”的同义词。

  • 客户端拿到什么?
    可验证的身份声明与过期信息。
  • 它的强项
    各服务共享验证材料便可独立验证,适合多终端与身份传递。
  • 它的代价
    签发后难即时收回;内容会随每次请求传输,声明变更未必即时生效。
常见误区纠正:“JWT 可以跨域、Session 不可以”不准确。跨源请求要看 CORS、Cookie 的 SameSite / Secure、浏览器隐私策略与是否携带凭证;JWT 放 Authorization 头只是避免了 Cookie 自动携带的那一组约束,并不绕过 CORS。
03 / trade-off matrix

比较的重点不是“谁先进”,而是谁承担成本

下表把“Cookie + Session”和“JWT Bearer”作为典型组合对比。JWT 放入 HttpOnly Cookie 时,安全边界会变成混合模型,需要把两列的措施一起考虑。

决策维度Cookie + SessionJWT(通常经 Authorization)面试中应说清的结论
真实状态位置服务端 Session Store令牌携带声明;纯验签时服务端无会话状态JWT 减少的是会话状态查询,不是消灭所有服务端数据。
即时吊销 / 强制下线直接删除 Session黑名单 / 版本号 / 短过期风控、封禁、权限即时收回优先考虑 Session 或给 JWT 补状态。
多机与微服务共享 Redis / 粘性会话共享验签密钥 / 公钥JWT 的价值是节点独立验签;Session 通过 Redis 也能可靠扩展。
浏览器安全面Cookie 自动发送:关注 CSRF;HttpOnly 可防 JS 直接读取。JS 可读存储:关注 XSS 窃取;若 JWT 放 Cookie,仍有 CSRF。不要回答“localStorage 更安全”——它对 XSS 更脆弱。
请求负载通常很小(sid)令牌随请求传输JWT Payload 只放必要声明,避免用户资料、权限大列表和敏感数据。
权限变更下一次读取即生效旧 token 可能仍含旧声明把鉴权策略与业务授权解耦;高敏操作可实时查权或要求再认证。
适配终端浏览器最自然;非浏览器可手动带 sid。App / 小程序 / API 调用统一不是“Session 不能给 App 用”,而是 JWT / opaque token 的客户端协议更顺手。
04 / scenario selector

按你的约束做选型,而不是按流行度做选型

试着切换条件:推荐会解释“为什么”,同时指出你为此付出的工程成本。

你的业务更像哪一种?

每项选一个最接近的答案。

05 / token anatomy

JWT 的三段式,不要把 Base64 当加密

JWT 的 Payload 可以被任何拿到令牌的人解码;签名解决的是防篡改与可验证性,不是保密。密码、身份证号、手机号、完整权限数据都不应放入普通 JWT Payload。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTYiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3MDAwMDAwMDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
HEADER

令牌类型与算法,例如 HS256RS256

PAYLOAD · 可解码

只放 subissaudexp、最小角色等必要声明。

SIGNATURE

服务端用密钥或私钥签发;验证端检查令牌没有被改过。

纯 JWT:少状态,弱控制

Loginlong JWTmany API calls

容易做,但一旦泄露、封禁或权限变化,往往只能等到过期。长期有效 JWT 通常不是面向用户登录的好默认值。

工程折中:短 Access + 可控 Refresh

15m access JWT+7d refresh (DB / Redis)rotation

Access Token 尽量短寿命;Refresh Token 可轮换、可撤销、可绑定设备。强制退出时撤销 refresh,并让短 access 自然过期;高风险接口还可查 token version。

06 / interview answer

让面试官看到业务判断,而不是背概念

回答顺序:承认替代方案价值 → 说清当前约束 → 解释收益和代价 → 给出安全补偿措施。

翻车回答

“我们用 JWT,因为它无状态,不占服务器内存,还可以跨域。Session 只能放内存,所以不适合分布式。”

为什么不够:忽略 Session 可用 Redis 共享;把跨域说成 JWT 独有;完全没说业务是否需要即时下线、客户端类型、权限变化和令牌泄露后的处理。

可直接使用的回答结构

我们没有把 JWT 当作“更先进的 Session”。项目是 多端客户端 + 多个 API 服务,因此用短期 JWT 在 Authorization 头中传递身份,让服务节点能独立验签,减少共享 Session 查询;但我们承认它的代价是撤销和权限变更不即时。

所以 Access Token 只保留 15 分钟,Payload 只含用户 ID、受众和最小角色;Refresh Token 记录在 Redis / 数据库中并做轮换,注销、封禁或密码修改时可立即撤销。若回到单体、只服务同站 Web 且需强制下线,我们会优先选 HttpOnly Cookie + Redis Session,因为控制更直接。
07 / security checklist

无论选谁,都要回答这四件事

01 · TRANSPORT

全链路 HTTPS;Cookie 用 Secure;不要把凭证放 URL,避免出现在 Referer 与日志中。

02 · XSS / CSRF

HttpOnly Cookie 降低读取风险,但需要 SameSite / CSRF Token / Origin 校验;JS 可读令牌则优先防 XSS。

03 · LIFECYCLE

定义过期、刷新、轮换与撤销。关键操作要求再认证,不把“登录一次永久有效”当成体验。

04 · VALIDATION

JWT 需固定允许算法,校验签名、expissaud;切勿只做 Base64 解码。