在构建 .NET Web API 后台时,为了实现在线人数统计,我们通常会引入 Redis 来存储用户的活跃状态。
这时,一个非常敏锐且直击架构本质的问题往往会浮出水面:
“既然为了统计在线人数,每次请求都要去 Redis 读写一次,那 JWT ‘无状态、不查库’ 的核心优势不就没了吗?干脆用一个短小的随机字符串(普通 Token),既能节省流量,又能节省计算资源,岂不更好?”
这是一个极好的问题。它触及了软件架构的核心——权衡 (Trade-off)。
答案是:在特定场景下,普通 Token 确实更好;但在大多数现代架构中,JWT + Redis 的组合依然具有不可替代的优势。
本文将从依赖性、性能、架构扩展性三个维度,深入剖析为什么我们依然推荐保留 JWT。
1. 核心区别:强依赖 vs. 弱依赖
这是两者最根本的区别,决定了系统的可用性 (Availability) 上限。
🔵 方案 A:普通 Token (Reference Token) + Redis
在这个方案中,Token 只是一个无意义的随机字符串(一把钥匙)。
-
流程: 请求到达 -> 解析 Token -> 必须请求 Redis 查找对应的 UserID -> 拿到身份 -> 执行业务。
-
风险: 这里 Redis 是强依赖。
-
如果 Redis 宕机、网络抖动或连接数耗尽,整个系统的认证模块瞬间瘫痪。
-
所有接口都会返回 401,用户无法进行任何业务操作。
-
🔴 方案 B:JWT (Self-contained) + Redis
在这个方案中,Token 包含数据(一张身份证),自带 UserID 和权限。
-
流程: 请求到达 -> CPU 校验签名 -> 直接拿到 UserID -> 执行业务。
-
统计(旁路): 顺便(甚至可以是异步地)去 Redis 续期一下在线状态。
-
优势: 这里 Redis 是弱依赖。
-
如果 Redis 宕机,仅仅是“在线人数统计”功能失效,或者无法强制踢人下线。
-
关键点: 用户的核心业务(下单、浏览、保存数据)依然可以正常进行。因为认证是靠 Web Server 本地的 CPU 计算完成的,不依赖外部存储。
-
结论: JWT 方案提供了更好的容灾能力。
2. 架构视野:微服务与前端体验
如果你的项目不仅仅是一个单体应用,JWT 的优势将形成降维打击。
微服务间的传递
-
普通 Token: 当请求从“网关”转发到“订单服务”时,“订单服务”拿到 Token 也是一脸茫然,它也得去查 Redis。这会导致内网流量激增和中心化存储瓶颈。
-
JWT: 无论请求流转到哪个微服务,服务只需拿公钥算一下即可验证身份。JWT 最核心的“节省”,省的是内网交互的复杂度。
前端开发体验
-
JWT: 前端拿到 Token 后,可以解析 Payload,直接获取
过期时间、用户名、角色、头像等信息用于 UI 展示,无需额外请求 API。 -
普通 Token: 前端只拿到一串乱码。要显示用户名?必须再发一个
GET /user/profile请求。
3. 总结:Redis 扮演的角色不同
回到最初的问题,引入 Redis 是否让 JWT 失去了意义?
没有。因为它们的分工不同。
在 JWT + Redis 的架构中:
-
JWT 是“通行证”: 负责高频、关键的身份验证。它保证了只要服务器活着,用户就能操作。
-
Redis 是“监控器”: 负责低频、辅助的状态记录。它负责统计谁来过,或者在必要时把坏人拦在外面(黑名单模式)。
这种设计实现了“认证逻辑”与“状态存储”的解耦 (Decoupling)。
🚀 决策指南:你应该怎么选?
-
选择 普通 Token + Redis 如果:
-
你主要开发单体应用,Redis 就在本地,访问极快。
-
你需要极致的安全控制(例如:点击“踢出”,用户必须毫秒级下线)。
-
你的客户端是 IoT 设备,对流量极其敏感,无法承受 JWT 几百字节的 Header。
-
-
选择 JWT + Redis 如果:
-
你正在构建(或未来可能迁移到)微服务架构。
-
你需要高可用性,不希望 Redis 故障导致全站瘫痪。
-
你的前端是富客户端(SPA/Mobile),需要利用 Token 中的用户信息。
-
对于大多数现代 .NET Web API 项目,JWT 做认证 + Redis 做统计 依然是兼顾性能、体验与稳定性的最佳实践。