Featured image of post 网络安全中 JWT 令牌与有状态会话的比较Featured image of post 网络安全中 JWT 令牌与有状态会话的比较

网络安全中 JWT 令牌与有状态会话的比较

关于撤销属性和本地安全性,批评无状态 JWT 令牌与有状态服务器数据库会话。

介绍

身份验证是每个 Web 应用程序的支柱。出现了两种主要模式:无状态 JWT(JSON Web 令牌) 身份验证和 基于状态会话 身份验证。两者都解决相同的问题——在后续请求中验证用户是谁——但它们在存储、撤销和安全属性方面有根本的不同。本文提供了详细的比较,以帮助您选择适合您的应用程序的方法。


智威汤逊结构

JWT 是一个独立的令牌,由三个以点分隔的 base64url 编码段组成:

header.payload.signature
// Header
{
  "alg": "HS256",
  "typ": "JWT"
}
// Payload
{
  "sub": "user123",
  "iat": 1712345678,
  "exp": 1712349278,
  "role": "admin"
}
// Signature (HMAC-SHA256 of header + payload)
细分内容
标题算法(HS256RS256)和令牌类型
有效负载声明 — sub(主题)、iat(发布于)、exp(过期)、自定义数据
签名验证令牌未被篡改

由于有效负载仅采用 Base64 编码(未加密),因此敏感数据绝不能放置在有效负载中,除非使用 JWE(JSON Web 加密)。


基于会话的身份验证

在基于会话的身份验证中,服务器存储会话数据(通常在内存、Redis 或数据库中)。客户端仅在 cookie 中保存会话 ID(随机的不透明字符串):


头对头比较

方面智威汤逊会议
存储位置客户端持有所有数据服务器保存会话数据
服务器状态无状态 — 无需数据库查找有状态 — 需要会话存储查询
可扩展性非常好 - 没有共享会话存储多实例需要集中式Redis/DB
撤销困难 — 有效期至 exp立即 — 从存储中删除会话
代币大小更大(数百字节)小(会话 ID ~32 字节)
XSS 漏洞JS (localStorage) 可访问的令牌JS 无法访问 httpOnly cookie
CSRF 保护需要人工处理SameSite cookie + CSRF 令牌

JWT 的撤销挑战

JWT 最显着的弱点是撤销。一旦发出,JWT 将保持有效,直到其 exp 声明为止。如果用户注销、更改密码或被禁止,则在没有服务器端状态的情况下令牌无法失效,这违背了无状态前提。

缓解策略

1.短期访问令牌+刷新令牌:

// Access token: 15 minutes
// Refresh token: 7 days (stored in database)

访问令牌的 TTL 很短,因此如果泄露,损害是有限的。刷新令牌存储在服务器端,因此可以撤销

2.令牌黑名单(拒绝名单):

// On logout, add jti (JWT ID) to Redis with TTL matching token expiry
await redis.set(`blacklist:${jti}`, 'true', 'EX', remainingTTL);

这会重新引入服务器状态,但仅针对已撤销的令牌,而不是所有活动会话。

3.轮换令牌签名密钥:

更改签名密钥会使所有令牌失效——这是一种生硬但有效的紧急工具。


XSS 和 XSRF 注意事项

威胁JWT(本地存储)会话(httpOnly cookie)
XSS令牌通过 document.cookielocalStorage 被盗JS 无法访问令牌(仅 http)
CSRF不容易受到攻击(手动授权标头)没有 SameSite 或 CSRF 令牌就容易受到攻击

存储在 localStorage 中的 JWT 容易受到 XSS - 任何注入的脚本都可以读取它们。 HttpOnly cookie 可以防止这种情况,但需要 CSRF 保护,因为 cookie 是自动发送的。

JWT 的最佳实践: 将访问令牌存储在 httpOnly、Secure、SameSite=Strict cookie(不是 localStorage)中。服务器从 Authorization 标头(而不是 cookie)读取它,以避免 CSRF。

// Set JWT in httpOnly cookie
res.cookie('token', jwt, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  maxAge: 15 * 60 * 1000
});

混合方法

许多生产系统结合了这两种模式:

方法访问令牌刷新令牌
仅限智威汤逊内存中的 JWT带有长 exp 的 JWT
会话式不透明会话 ID
混合短暂的 JWT(15 分钟)数据库中不透明的刷新令牌

混合模型为您提供 JWT 对于大多数请求的无状态效率,同时通过刷新令牌保留撤销功能


决策矩阵

您的首要任务推荐方法
最小的服务器数据库负载JWT(无状态)
即时用户注销/禁止基于会话的
微服务/API网关JWT(传递)
移动应用程序JWT(无 cookie 存储)
服务器渲染的 Web 应用程序会话(httpOnly cookie)
第三方API接入JWT(不记名令牌)

结论

没有普遍的赢家。 JWT 在分布式系统、移动应用程序和 API 优先架构方面表现出色,在这些架构中,无状态性非常有价值。会话身份验证为撤销、注销和服务器端安全实施提供高级控制。混合模式——由可撤销刷新令牌支持的短期 JWT——提供了一种务实的折衷方案,既发挥了两种方法的优点,又减轻了它们的缺点。