登录鉴权是每个系统的第一道门,而"token 存哪里"是这个模块最核心的架构决策。同样是登录成功后给前端发一个 token,redis 会话机制和 jwt 机制背后是两种截然不同的架构哲学:前者把状态留在服务端,服务端掌握绝对控制权;后者把状态推给客户端,服务端彻底"失忆"换取无状态扩展能力。
本文基于一张完整的运行过程对比图,分三部分展开:第一部分拆解 redis 会话(session)机制的完整运行链路,第二部分拆解 jwt 机制的完整运行链路,第三部分给出七个维度的对比总结和可落地的选型建议。
第一部分:redis 会话(session)机制运行过程

1.1 总体思路:服务端记住一切
redis 会话机制的本质是"服务端记住一切"。登录成功后,服务端生成一把无意义的、不可伪造的"钥匙"(session_token),把真正的用户身份信息作为"行李"寄存在 redis 里,然后把钥匙通过 cookie 交给浏览器。之后每次请求,浏览器自动带钥匙上门,服务端拿钥匙去 redis 开柜取行李。
这个模型的关键词是:token 本身没有信息量,它只是一个索引。
1.2 登录阶段的完整执行链路
step 1:用户登录
前端提交账号 + 密码(明文,依赖 https 保护传输安全),请求 post /login (account, password)。
step 2:查 mysql
服务端查询 users 表,获取用户信息:(id, username, password_hash, status)。注意这里取出的是密码哈希,绝不存储明文密码。
step 3:密码校验
使用 bcrypt.checkpw(明文密码, 数据库 password_hash) 进行校验:
- 匹配失败,直接返回登录失败;
- 匹配成功且账号未被封禁(status 正常),流程继续。
bcrypt 自带盐值且计算成本可调,是目前密码存储的工业标准,这一步在两种机制中完全一致。
step 4:雪花算法生成 session_token
用雪花算法(snowflake)生成全局唯一的 session_token。它就是那把"会话钥匙":无业务含义、不可猜测、天然适合分布式发号。
step 5:写入 redis
把会话数据写入 redis,这是整个机制的核心动作:
- key: session:{session_token}
- value: json(user_id, role, 用户信息快照)
- ttl: 24 小时过期
ttl 的设置让会话天然具备"到期自动销毁"的能力,不需要额外的清理任务。
step 6:下发 cookie + 返回用户信息
通过响应头下发凭证:
set-cookie: fitmall_session=session_token; httponly; path=/
同时返回 json(user: {昵称, 头像...}),前端可将其存入 localstorage 用于页面渲染。注意区分这两份数据:cookie 里的 session_token 是鉴权凭证,localstorage 里的用户资料只是展示数据,前者决定"你是谁",后者只负责"页面画什么"。
1.3 后续请求:浏览器自动携带 cookie
登录之后,浏览器会在每次请求的请求头中自动携带 cookie: fitmall_session=xxx。这是 cookie 的天然行为,前端不需要写任何鉴权相关代码。
1.4 后端鉴权流程
服务端收到请求后的鉴权动作只有两步:
- 从 cookie 中取出 session_token;
- 去 redis 查询 key: session:{session_token}:
- 查到,鉴权通过,放行;
- 查不到(不存在或已过期),会话失效,返回 401 未登录。
1.5 访问业务数据
鉴权通过后,服务端根据 user_id 去 mysql 查询真实业务数据(如订单、资料等),返回给前端。至此一次完整的请求闭环结束。
1.6 redis 会话机制特点
| 特点 | 说明 |
|---|---|
| 服务端存储会话 | 会话信息存储在 redis 中,key 为 session:{session_token},value 为用户身份信息 + ttl |
| 安全性高 | cookie 设置 httponly 后,js 无法读取,天然防 xss 窃取凭证 |
| 可主动失效 | 删除 redis 中的 key,即可立即让指定用户下线 |
| 服务端有状态 | 每次请求都需要访问一次 redis,鉴权依赖外部存储 |
| 扩展性 | 需要保证 redis 高可用;但因为会话集中存储,反而天然支持分布式 session 共享,多台应用服务器无差别鉴权 |
第二部分:jwt 机制运行过程

2.1 总体思路:客户端自带一切
jwt(json web token)机制的本质是"客户端自带一切"。服务端在登录成功后,把用户身份信息直接编码进 token 并加上密码学签名,然后彻底"失忆",服务端不存任何会话数据。之后每次请求,前端出示这张"身份证",服务端只做两件事:验真伪(签名校验)、查有效期(exp 检查)。
这个模型的关键词是:token 本身就是信息载体,验签通过即信任。
2.2 登录阶段的完整执行链路
step 1:查 mysql 验证用户
查询 users 表,使用 bcrypt 校验账号密码。这一步与 redis 会话机制完全相同,登录入口的安全性不因为 token 方案不同而有差别。
step 2:生成 jwt payload
构造包含用户身份与有效期的载荷:
payload = {
"user_id": 123,
"role": "user",
"exp": 1719220000
}需要特别强调:payload 只是 base64 编码,不是加密,任何人拿到 token 都能解码查看内容,所以绝不能在 payload 里放密码、手机号等敏感信息。
step 3:签名生成 jwt
使用密钥(对称的 hs256 或非对称的 rs256)对 header + payload 计算签名,拼出完整的 jwt 字符串。签名的意义在于:服务端可以识别出任何对 payload 的篡改,改一个字节,验签就会失败。
step 4:返回 jwt 给前端
把完整 jwt 返回给前端,由前端自行存储在 localstorage 或 cookie 中。服务端到此为止,不落下任何状态。
2.3 后续请求:前端主动携带 jwt
与 cookie 的自动携带不同,jwt 需要前端在每次请求时显式地把 token 放进请求头:
authorization: bearer eyjhbgcioijiuzi1niis...
携带的是整条 jwt 字符串。
2.4 后端鉴权流程(无需查 redis)
这是 jwt 机制最有吸引力的地方,鉴权完全在本地计算完成:
- 从 authorization 头中取出 jwt;
- 使用密钥校验签名合法性;
- 校验通过,解析 payload,拿到 user_id、role、exp;
- 检查是否过期(exp):
- 未过期,鉴权通过,放行;
- 已过期,返回 401 未登录。
整个过程不查 redis、不查数据库,一次签名运算就完成鉴权。
2.5 访问业务数据
鉴权通过后,同样根据 user_id 去 mysql 查询真实业务数据(如订单、资料等)。可以看到,两种机制的差异只在"认人"环节,业务数据访问环节完全一致。
2.6 jwt 机制特点
| 特点 | 说明 |
|---|---|
| 客户端存储全部信息 | jwt 自身包含用户身份信息,服务端无需存储会话 |
| 无状态 | 每次请求只需校验 jwt 签名,不依赖 redis,鉴权成本是一次本地运算 |
| 可扩展性强 | 任何服务节点用同一把密钥(或公钥)即可独立验签,天然适合分布式、微服务架构 |
| 安全性 | signature 防篡改,可配合 https;建议存储在 httponly cookie 中降低 xss 窃取风险 |
| 最大短板:无法主动失效 | 只要没过期就一直有效;密码修改、强制下线无法立即生效;若需主动失效,必须引入黑名单 redis,等于放弃无状态优势 |
第三部分:对比总结与选型建议
3.1 七维对比表
| 对比项 | redis 会话(session)机制 | jwt 机制 |
|---|---|---|
| 存储位置 | 服务端 redis 存储会话信息 | 客户端存储 jwt |
| 鉴权方式 | 每次请求查 redis | 每次请求校验 jwt 签名(无需查 redis) |
| 状态 | 有状态 | 无状态 |
| 主动失效 | 可主动删除 redis key 立即失效 | 默认无法主动失效(需黑名单方案) |
| 安全性 | 高(cookie httponly + redis 存储) | 较高(签名防篡改,但 payload 明文可解码) |
| 性能 | 每次请求多一次 redis 查询 | 性能更好,无需查 redis |
| 适用场景 | 适合需要强制下线、会话管理的系统 | 适合分布式、微服务、移动端、前后端分离 |
3.2 差异的本质:状态在谁手里
把七行对比收敛成一句话:状态在谁手里,谁就掌握主动权,同时谁就承担可用性责任。
- redis 会话机制把状态握在服务端手里,换来的是控制力(随时踢人、会话管理),代价是 redis 成为每次请求的必经之路,必须保证高可用;
- jwt 机制把状态交给客户端,换来的是无状态扩展和鉴权性能,代价是签发出去就收不回来,过期之前只能信任。
理解了这一层,选型就不再是"哪个更先进",而是"我的系统更缺什么"。
3.3 选型建议
选 redis 会话机制,当:
- 需要主动下线 / 踢人(如风控场景、账号封禁立即生效);
- 需要会话管理(查看在线用户、单点登录互踢);
- 对安全要求极高(凭证不落前端可读区域);
- 系统为单体或传统架构,引入 redis 的边际成本低。
选 jwt 机制,当:
- 系统是分布式 / 微服务架构,不希望鉴权环节存在共享存储依赖;
- 需要无状态水平扩展,服务节点随意增减;
- 对性能要求高,无法接受每次请求多一次 redis 网络往返;
- 移动端 / 第三方接入场景,cookie 天然不适用的环境。
3.4 架构师的实践补充
真实项目里往往不是二选一,几个工程上常用的折中方案值得知道:
- 短寿命 access token(jwt)+ 长寿命 refresh token(redis 存储):access token 10-30 分钟过期,保证鉴权走无状态快路径;refresh token 存 redis,过期后用它换新,同时保留"删除 refresh token 即踢人下线"的控制力。这是目前中大型系统最主流的混合方案。
- jwt 黑名单是有代价的:很多人给 jwt 打"黑名单补丁"来实现主动失效,但黑名单必须每次请求都查询,本质上把无状态又变回了有状态,而且黑名单数据结构和 redis 会话表几乎同构。如果你的系统强依赖强制下线,不如一开始就用会话机制,不要用 jwt 模拟。
- redis 高可用是硬前提,不是加分项:会话机制下 redis 一旦宕机,全站用户集体掉线。哨兵或集群部署、持久化策略、降级预案,都是上线前必须回答的问题。
- jwt 的 payload 是明文:无论用哪种存储方式,payload 只放
user_id、role、exp这类非敏感字段,这是不可妥协的红线。
结语
redis 会话机制与 jwt 机制没有高下之分,它们是对"信任与状态应该放在哪里"这一问题的两种回答。会话机制信任服务端的存储,jwt 信任密码学的签名。作为架构师,需要做的不是站队,而是看清自己系统的控制力诉求、扩展性诉求和运维成本底线,然后把票投给最匹配的那一个。如果你的业务同时需要两者的好处,那么"短期 jwt + 长期 refresh token"的混合架构,值得作为默认起点。
到此这篇关于redis会话机制和jwt机制深度解析的文章就介绍到这了,更多相关redis会话机制和jwt机制内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论