目录

背景

方案一:纯 JWT 手动实现

架构设计

优点

缺点

适用场景

方案二:Spring Authorization Server + 随机字符串 Token

架构设计

Token 存储结构(数据库)

优点

缺点

适用场景

方案三:Spring Authorization Server + JWT(推荐)

架构设计

JWT Token 结构示例

为什么还需要 Redis?

优点

缺点

适用场景

三种方案对比总结

功能对比表

性能对比

技术选型建议

选择 纯 JWT 手动实现 如果:

选择 Spring Authorization Server + 随机 Token 如果:

选择 Spring Authorization Server + JWT(推荐)如果:

总结


本文基于实际项目经验,深入对比三种主流认证方案的优劣,旨在为微服务架构中的认证授权技术选型提供参考。

背景

在构建微服务架构时,认证与授权是绕不开的核心环节。近期,我在两个项目中分别接触到了不同的认证方案:aks 项目使用了旧版的 spring-security-oauth2 配合随机字符串 Token;而 yj 项目则采用了更新的 Spring Authorization Server 并生成 JWT。这促使我思考,究竟有哪些主流方案?它们各自的优缺点是什么?哪种最适合我的下一个项目?

经过一番研究,我发现主要有以下三种方案值得深入探讨。

方案一:纯 JWT 手动实现

架构设计

这种方案通常不依赖完整的 OAuth 2.0 框架,而是开发者自行实现一个登录接口,验证用户凭据后,手动调用 JWT 库生成 Token

功能实现方式复杂度
Token 生成手动调用 JWT 库⭐⭐
Token 验证手动解析 + 验签⭐⭐
Refresh Token自己设计机制⭐⭐⭐⭐
客户端管理自己设计表结构⭐⭐⭐
授权范围 (Scopes)自己设计 claims⭐⭐⭐
多设备登录策略自己实现逻辑⭐⭐⭐⭐
Token 注销需要配合 Redis 黑名单⭐⭐⭐⭐

优点

  • ✅ 简单直接:对于快速验证想法或开发小型内部工具非常方便。
  • ✅ 完全可控:所有逻辑都在你的掌控之中,可以根据特定需求灵活调整。
  • ✅ 无额外依赖:只需要引入一个 JWT 库(如 jjwt)。

缺点

  • ❌ 重复造轮子:完整的 OAuth2 授权流程(如授权码模式、PKCE、令牌交换等)需要你自己实现,容易遗漏安全细节。
  • ❌ 容易出错:JWT 的签名、过期验证、防篡改等逻辑若实现不当,会引入严重的安全漏洞。
  • ❌ 维护成本高:随着业务发展,处理 Refresh Token、多设备登录、令牌撤销等功能会变得越来越复杂。
  • ❌ 标准化程度低:前端或第三方系统对接时,没有统一的标准可循,增加了沟通成本。

适用场景

  • 内部小工具、Demo 项目
  • 快速原型验证
  • 不涉及复杂 OAuth2 流程或第三方集成的简单系统

方案二:Spring Authorization Server + 随机字符串 Token

架构设计

这是 Spring 官方推荐的新一代 OAuth 2.0 授权服务器实现。它严格按照标准,生成不透明的随机字符串 Token,并将其存储在数据库或缓存中。

Token 存储结构(数据库)

Spring Authorization Server 默认会使用 JdbcOAuth2AuthorizationService 等组件将授权信息持久化到数据库。oauth2_authorization 表中会包含一个 access_token_value 字段,其值就是一个不透明的随机字符串。

优点

  • ✅ OAuth2 标准流程:开箱即用地支持授权码模式、客户端凭证模式等多种标准流程。
  • ✅ 客户端管理:内置了对注册客户端的支持,包括 ID、密钥、重定向地址等。
  • ✅ Refresh Token 机制:框架自动处理 Refresh Token 的生成、验证和轮换。
  • ✅ Scopes 管理:标准化地管理授权范围。
  • ✅ 主动注销:可以通过 OAuth2AuthorizationService 删除数据库中的记录来实现令牌的即时失效。

缺点

  • ❌ Token 验证性能:每次资源服务器需要验证 Token 时,都必须通过 OAuth2Introspector 查询数据库或缓存,这在网络和数据库层面引入了延迟和依赖。
  • ❌ 跨服务传递:下游服务验证 Token 时同样需要访问授权服务器或共享存储,增加了系统间的耦合。
  • ❌ 微服务架构适配:在高并发场景下,中心化的验证服务可能成为性能瓶颈。

适用场景

  • 单体应用或简单的分布式系统
  • Token 验证频率不高的场景
  • 需要严格的 Token 主动注销控制的场景

方案三:Spring Authorization Server + JWT(推荐)

架构设计

这是当前最推荐的方案,它结合了 Spring Authorization Server 的标准流程和 JWT 的无状态验证优势。授权服务器生成一个自包含用户信息和签名的 JWT,资源服务器可以独立验证。

JWT Token 结构示例

生成的 Token 是一个由三个 Base64 编码字符串组成的字符串,中间用 . 分隔。例如:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsInVzZXJJZCI6IjEyMzQ1Njc4OTAiLCJyb2xlcyI6WyJST0xFX0FETUlOIiwiUk9MRV9VU0VSIl0sInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdLCJpYXQiOjE3MTA5MjE2MDAsImV4cCI6MTcxMDkyODgwMCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgxIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

它包含 Header、Payload 和 Signature 三部分。Payload 部分可能如下:

{
  "sub": "admin",
  "userId": "1234567890",
  "roles": ["ROLE_ADMIN", "ROLE_USER"],
  "scope": ["read", "write"],
  "iat": 1710921600,
  "exp": 1710928800,
  "iss": "http://localhost:8081"
}

为什么还需要 Redis?

虽然 JWT 本身是自包含的,但在实际应用中,往往需要一些 JWT 本身无法直接提供的功能,这时就需要 Redis 作为补充:

表格

功能JWT 独立能力需要 Redis说明
验证签名✅ 支持使用公钥验证 JWT 签名
检查过期✅ 支持JWT claims 中包含 exp 字段
提取用户信息✅ 支持JWT claims 中包含 subuserId 等
主动注销❌ 不支持✅ 支持JWT 一旦签发,无法撤销,需在 Redis 中维护黑名单或删除记录
自动续期❌ 不支持✅ 支持JWT 过期时间固定,可通过拦截器检查剩余时间并在 Redis 中延长其有效状态
查询用户 Token❌ 不支持✅ 支持通过 principal → accessToken 映射快速定位用户当前 Token
限制单用户单 Token❌ 不支持✅ 支持通过 Redis 实现,当新 Token 生成时,使旧 Token 失效

优点

  • ✅ OAuth2 标准流程:继承了方案二的所有优点,流程标准化。
  • ✅ 高性能验证:资源服务器无需查询数据库或授权服务器,本地即可验证签名和过期时间,性能极高。
  • ✅ 跨服务传递:JWT 自包含,可以轻松在微服务间传递,无需额外的验证步骤。
  • ✅ 微服务适配:完美契合微服务无状态、去中心化的思想。
  • ✅ 灵活的 Token 管理:结合 Redis,可以实现主动注销、自动续期、查询用户 Token 等高级功能。
  • ✅ 标准化:前端和第三方系统对接有统一、成熟的方案。

缺点

  • ⚠️ 架构复杂度:需要理解 OAuth2、JWT、Redis 以及它们之间的协作关系。
  • ⚠️ JWT 无法撤销(固有问题):虽然可以通过 Redis 黑名单等方式缓解,但这需要额外的开发和运维工作。

适用场景

  • ✅ 微服务架构(推荐)
  • ✅ 高并发场景
  • ✅ 需要跨服务认证
  • ✅ 需要对接第三方系统
  • ✅ 长期维护的企业级应用

三种方案对比总结

功能对比表

表格

特性纯 JWT 手动实现Spring AS + 随机 TokenSpring AS + JWT
授权流程标准化❌ 自己实现✅ OAuth2 标准✅ OAuth2 标准
客户端管理❌ 自己实现✅ 内置支持✅ 内置支持
Token 验证性能✅ 无需查库❌ 需查库/Redis✅ 无需查库
跨服务传递✅ 自包含❌ 需查库验证✅ 自包含
Refresh Token❌ 自己实现✅ 内置支持✅ 内置支持
主动注销❌ 需黑名单✅ 删除 Token✅ Redis 删除
自动续期❌ 难实现❌ 难实现✅ Redis 实现
多设备登录策略❌ 自己实现⚠️ 较复杂✅ Redis 实现
微服务适配⚠️ 需自己整合⚠️ 性能瓶颈✅ 最佳实践
实施复杂度⭐⭐⭐⭐⭐⭐⭐⭐⭐

性能对比

在高并发场景下,Token 验证的性能至关重要。

技术选型建议

选择 纯 JWT 手动实现 如果:

  • 项目规模小,2-3 人开发
  • 不需要对接第三方系统
  • 快速原型验证,后期可能重构
  • 团队对 OAuth2 不熟悉,学习时间有限

选择 Spring Authorization Server + 随机 Token 如果:

  • 单体应用或简单分布式系统
  • Token 验证频率不高(< 100 QPS)
  • 需要严格的 Token 注销控制
  • 所有服务都在同一个信任网络内

选择 Spring Authorization Server + JWT(推荐)如果:

  • 微服务架构(多个独立服务)
  • 高并发场景(> 100 QPS)
  • 需要跨服务认证(下游服务需要用户信息)
  • 需要对接第三方系统(标准化 OAuth2 接口)
  • 企业级长期维护项目

总结

表格

方案推荐指数适用场景
纯 JWT 手动实现⭐⭐小工具/Demo
Spring AS + 随机 Token⭐⭐⭐单体应用/低并发
Spring AS + JWT⭐⭐⭐⭐⭐微服务/企业级

核心结论

  1. 不要重复造轮子:OAuth2 标准流程已有成熟实现,使用 Spring Authorization Server 可以避免大量潜在的安全隐患。
  2. JWT 是微服务首选:其自包含、无状态的特性使其在微服务架构中具有天然的优势。
  3. Redis 是必要补充:虽然 JWT 本身无法撤销,但通过 Redis 可以有效管理令牌的生命周期,弥补其不足。
  4. Spring Authorization Server + JWT 是当前构建现代、安全、高性能认证授权系统的最优组合。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐