JWT和Session基础

用户登录之后,服务器怎么「记住」他是谁?这个问题看似简单,却是所有 Web 应用用户系统的基石。选错认证方案,轻则用户体验糟糕(频繁掉登录),重则安全漏洞百出(会话劫持、Token 泄露)。本文深入拆解 Session 和 JWT 两种主流认证机制的原理、差异与适用场景,帮助你在实际项目中做出合理选择。

一、为什么需要会话管理

HTTP 协议本身是无状态的——每一次请求对服务器来说都是独立的,它不会自动记住「上一次请求来自谁」。但几乎所有 Web 应用都需要在多个请求之间维持用户的登录状态:你登录了邮箱,浏览收件箱、打开邮件、撰写回复,这些请求之间服务器必须知道「这些都是你」。

解决这个问题的两大主流方案就是 SessionJWT。它们的根本区别在于:状态信息存放在哪里。Session 把状态存在服务器端,JWT 把状态存在客户端。

二、Session 机制原理

2.1 核心流程

Session 认证的过程可以用四个步骤概括:

  1. 用户提交凭证:用户通过登录表单提交用户名和密码。
  2. 服务器验证并创建 Session:服务器验证凭证通过后,在服务端存储一份会话数据(包含用户 ID、角色、登录时间等),并生成一个唯一的 Session ID
  3. 返回 Session ID 给客户端:服务器通过 HTTP 响应头的 Set-Cookie 字段,将 Session ID 写入浏览器的 Cookie。
  4. 后续请求自动携带:浏览器在后续每次请求中自动带上这个 Cookie,服务器根据 Session ID 查找对应的会话数据,从而识别用户身份。
流程图画布 · 115%
Mermaid 流程图加载中...

2.2 Session ID 的存储方式

Session ID 需要通过某种方式在客户端和服务器之间传递。最常见的载体是 Cookie——浏览器会自动在每个请求中携带对应域名下的 Cookie,开发者无需手动处理。

除了 Cookie,Session ID 也可以通过 URL 参数传递(例如 ?sessionId=abc123),但这种方式存在安全风险(URL 会被记录到浏览器历史、服务器日志中),现代应用已经很少使用。

2.3 服务端的 Session 存储

Session 数据需要存储在服务端的某个地方。常见的存储方案包括:

  • 进程内存:最简单的方案,直接存在应用服务器的内存中。单机开发环境够用,但分布式部署时不同服务器之间的 Session 无法共享。
  • Redis / Memcached:将 Session 存入集中式的缓存服务,多台应用服务器共享同一份 Session 数据。这是生产环境中最常见的做法。
  • 数据库:将 Session 存入关系型数据库或 NoSQL 数据库。适合需要持久化 Session 的场景,但性能不如 Redis。

三、JWT 机制原理

3.1 什么是 JWT

JWT(JSON Web Token)是一种基于 JSON 的开放标准(RFC 7519),用于在各方之间安全地传输声明信息。它的核心特点是自包含——Token 本身就携带了所有必要的用户信息,服务器不需要额外查询存储。

3.2 JWT 的结构

一个 JWT 由三部分组成,用 . 连接:xxxxx.yyyyy.zzzzz。每一部分都经过 Base64URL 编码。

部分内容说明
Header{"alg": "HS256", "typ": "JWT"}声明 Token 类型和签名算法
Payload{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}携带声明数据(用户信息、过期时间等)
SignatureHMACSHA256(base64Url(header) + "." + base64Url(payload), secret)用于验证 Token 完整性,防止篡改

其中,Payload 里常见的标准声明(Claims)包括:

  • sub(Subject):Token 的主题,通常是用户 ID
  • iss(Issuer):签发者
  • exp(Expiration Time):过期时间
  • iat(Issued At):签发时间
  • aud(Audience):受众

需要注意的是,Payload 部分只是 Base64URL 编码,并非加密。任何人都可以解码看到里面的内容,所以绝对不要把密码等敏感信息放进 Payload。

3.3 核心流程

JWT 认证的关键在于签名验证——服务器通过密钥验证 Token 是否被篡改,无需查询任何存储。

流程图画布 · 115%
Mermaid 流程图加载中...

注意这里的关键区别:服务器不需要查询数据库或 Redis,只需要用本地密钥做一次签名验证。这就是 JWT「无状态」的含义。

3.4 签名算法

JWT 支持多种签名算法,主要分为两类:

  • 对称算法(如 HS256):签发和验证使用同一个密钥。适合单体应用,简单高效。
  • 非对称算法(如 RS256):签发用私钥,验证用公钥。适合微服务和跨服务场景——签发服务持有私钥,各个消费服务只需要公钥即可验证,不需要共享密钥。

四、Session vs JWT 对比

4.1 核心维度对比

维度SessionJWT
状态存储服务端(内存、Redis、数据库)客户端(Cookie、LocalStorage)
可扩展性需要共享存储,分布式部署复杂度较高天然无状态,水平扩展简单
服务器开销每个活跃用户占用一份存储无存储开销,只消耗签名验证的 CPU
Token 大小Session ID 通常很短(几十字节)JWT 较长(通常几百字节到几 KB)
主动撤销直接删除服务端 Session 即可立即失效无法直接撤销,需引入黑名单或等待过期
跨域支持Cookie 方案跨域处理复杂通过 HTTP Header 传递,跨域方便
移动端适配依赖 Cookie 机制,移动端需额外处理直接存储在客户端,APP 使用更方便
实时权限变更下次请求立即生效(查服务端数据)需要等 Token 过期或引入额外机制

4.2 安全模型对比

安全威胁Session 的风险JWT 的风险
XSS(跨站脚本攻击)Session ID 存在 HttpOnly Cookie 中时风险较低Token 存在 LocalStorage 中时,XSS 可直接窃取
CSRF(跨站请求伪造)Cookie 方案天然面临 CSRF 风险,需加 SameSite 或 CSRF Token使用 Authorization Header 传递时不受 CSRF 影响
Token 泄露Session ID 泄露后攻击者可冒充用户JWT 泄露后在过期前持续有效,且无法服务端撤销
中间人攻击必须使用 HTTPS 保护必须使用 HTTPS 保护
会话固定攻击登录前后需重新生成 Session ID不适用(每次登录签发新 Token)

五、如何选择

5.1 选择决策矩阵

项目特征推荐方案原因
小型单体应用、用户量有限Session实现简单,运维成本低
分布式 / 微服务架构JWT无状态,不需要共享 Session 存储
需要跨域认证(多子域名、第三方调用)JWTHTTP Header 传递,跨域无障碍
移动端 APP + Web 共用JWT一套 Token 机制适配多端
需要实时踢人下线、权限即时生效Session服务端直接删除 Session 即可
高安全要求(金融、政务)Session(或 JWT + 短过期 + 刷新)可控性强,出问题可立即切断
SPA(单页应用)JWT 或 Session + BFF 模式取决于是否需要跨域和微服务集成

5.2 不是非此即彼

实际工程中,很多项目会混合使用两种方案。例如:

  • JWT + 服务端黑名单:用 JWT 做无状态认证,同时在服务端维护一个已撤销 Token 的黑名单(通常存 Redis,设置与 Token 剩余有效期相同的 TTL)。兼顾了 JWT 的扩展性和 Session 的可撤销性。
  • JWT + Refresh Token:Access Token 使用短过期时间(如 15 分钟),配合一个长期有效的 Refresh Token(存在服务端或 HttpOnly Cookie 中)。Access Token 过期后用 Refresh Token 换取新的。
  • Session + BFF(Backend For Frontend):前端用 Session 管理登录态,BFF 层负责将 Session 转换为 JWT 调用后端微服务。

六、安全考虑

6.1 Session 安全要点

  • 设置 Cookie 安全属性HttpOnly 防止 JavaScript 读取、Secure 限制只在 HTTPS 下传输、SameSite=StrictSameSite=Lax 防止 CSRF。
  • 登录后重新生成 Session ID:防止会话固定攻击(Session Fixation)。
  • 设置合理的过期时间:空闲超时(如 30 分钟无操作自动过期)和绝对超时(如 24 小时强制重新登录)。
  • 使用 Redis 集中存储时,确保 Redis 实例本身的访问安全和网络隔离。

6.2 JWT 安全要点

  • 不要存放敏感信息:Payload 只是编码,不是加密。密码、身份证号等绝对不能放进 JWT。
  • 设置合理的过期时间:JWT 一旦签发,在过期前一直有效。过期时间越短,泄露后的风险窗口越小。
  • Token 存储位置:存在 LocalStorage 中容易受 XSS 攻击;存在 HttpOnly Cookie 中可以规避这个问题,但需要处理 CSRF。
  • 使用强密钥:对称算法的密钥至少 256 位,非对称算法的私钥妥善保管。
  • 验证所有字段:除了签名,还要验证 iss(签发者)、aud(受众)、exp(过期时间)等声明。

6.3 通用安全原则

无论使用 Session 还是 JWT,以下原则都适用:

  • 强制 HTTPS:所有认证相关的通信必须走 HTTPS,防止中间人攻击。
  • 限制登录尝试频率:防止暴力破解。
  • 记录安全日志:登录、登出、Token 刷新、异常请求等关键事件都需要记录。
  • 遵循 OWASP 指南OWASP Session Management Cheat SheetNIST SP 800-63B 是业界公认的安全基线。

七、实际案例

案例 1:单体电商后台管理系统

某出海电商的后台管理系统,技术栈为 Next.js + Express,用户量约 500 个运营人员。系统只需要支持 Web 端,不需要跨域调用。

方案选择:Session + Redis

理由:单体应用、用户量可控、不需要跨域、需要即时踢人下线能力(员工离职或权限变更)。Session 方案实现简单,通过 Redis 存储 Session 数据,运维成本也低。运营人员登录后台后,Session ID 通过 HttpOnly + Secure + SameSite=Strict 的 Cookie 传递,安全性有保障。

案例 2:AI SaaS 平台的 API 服务

某 AI 产品出海项目提供 SaaS 服务,前端是 SPA,后端是多个微服务(用户服务、计费服务、AI 调用服务),同时提供 OpenAPI 供第三方开发者调用。

方案选择:JWT(RS256)+ Refresh Token

理由:微服务架构下,Session 共享的复杂度太高。JWT 的无状态特性让每个微服务可以独立验证 Token,不需要互相通信。使用 RS256 非对称签名,由认证服务持有私钥签发 Token,其他服务只需要公钥验证。SPA 前端将 Access Token 存在内存中(变量),Refresh Token 存在 HttpOnly Cookie 中,兼顾安全性和跨域能力。Access Token 有效期 15 分钟,Refresh Token 有效期 7 天。

八、实施检查清单

无论选择哪种方案,以下检查项都值得逐条确认:

Session 方案检查清单

  • Cookie 设置了 HttpOnlySecureSameSite 属性
  • 用户登录后重新生成了 Session ID
  • Session 设置了合理的过期时间(空闲超时 + 绝对超时)
  • 分布式部署时使用了集中式 Session 存储(如 Redis)
  • 登出时正确清除了服务端 Session 数据
  • 敏感操作(修改密码、支付)要求二次验证

JWT 方案检查清单

  • Payload 中没有包含密码等敏感信息
  • 使用了足够强的签名密钥(对称 ≥ 256 位)
  • 设置了合理的过期时间(建议 15 分钟 ~ 1 小时)
  • 服务端验证了 issaudexp 等标准声明
  • Token 存储位置考虑了 XSS 风险(LocalStorage vs HttpOnly Cookie)
  • 实现了 Token 刷新机制(Refresh Token 或滑动过期)
  • 有 Token 撤销方案(黑名单或短过期 + 刷新)
  • 所有认证通信强制走 HTTPS

九、小结

Session 和 JWT 不是「谁更好」的关系,而是在不同约束条件下的权衡取舍。Session 把状态留在服务器,换来的是即时可控性和简单的安全模型;JWT 把状态交给客户端,换来的是无状态的扩展性和跨平台的灵活性。

对于 AI 产品出海项目,如果你的初期是单体架构、用户量有限,Session 是稳妥的起步选择;如果从第一天就规划了微服务、多端、开放 API,JWT 会帮你减少很多架构上的麻烦。理解两者的原理和边界,才能在实际场景中做出适合你的选择。

参考资料

  1. RFC 7519 - JSON Web Token (JWT) — IETF 官方 JWT 规范
  2. JWT.io - Introduction — JWT 入门指南与在线调试工具
  3. Auth0 - JSON Web Token Structure — JWT 结构详解
  4. OWASP - Session Management Cheat Sheet — OWASP 会话管理安全速查表
  5. NIST SP 800-63B - Session Management — NIST 会话管理官方指南
  6. LoginRadius - JWT vs Session Authentication: Real Scaling Differences — JWT 与 Session 的扩展性对比分析
  7. Logto Blog - JWT vs Session Authentication — 认证方案选型实践指南