jwt和token详解
要理解 JWT 和 Token 的关系,核心是先明确 “Token 是广义概念,JWT 是 Token 的一种具体实现”—— 所有 JWT 都是 Token,但并非所有 Token 都是 JWT。下面分两部分详细拆解:
¶一、先搞懂:什么是 Token?
Token(令牌) 是服务器颁发给客户端的「身份凭证」,本质是一段无意义的随机字符串(或结构化数据),用于解决 “反复验证身份” 的问题。
¶Token 的核心作用:替代密码,简化认证
比如你登录 App 的流程:
- 首次登录:你输入账号密码 → 服务器验证通过后,生成一个唯一的 Token(如
a1b2c3d4...),返回给你的手机; - 后续操作:你刷首页、看订单时,App 会自动在请求头里带上这个 Token → 服务器只需验证 Token 是否有效(无需再查密码),就能确认 “你是已登录的合法用户”。
¶Token 的特点:
- 无意义性:传统 Token(如随机字符串)本身不包含任何用户信息,服务器需要查数据库 / 缓存才能知道 “这个 Token 对应哪个用户”;
- 灵活性:Token 的格式、有效期、验证逻辑可自定义(比如有的用 UUID,有的用加密字符串);
- 安全性:Token 只在客户端和服务器之间传递,且通常通过 HTTPS 传输,避免被窃取。
¶二、再深入:什么是 JWT?
JWT(JSON Web Token) 是 Token 的一种标准化、结构化实现,它的核心改进是:把用户信息直接嵌入 Token 中,让服务器无需查数据库就能验证身份。
¶1. JWT 的结构:3 段式字符串(用.分隔)
JWT 的完整格式类似:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsInVzZXJOYW1lIjoiSmFja3kiLCJleHAiOjE3MTY2NTM2MDJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
这 3 段分别对应 Header(头部)、Payload(载荷)、Signature(签名),每段都是 Base64URL 编码(不是加密,可解码)。
| 部分 | 作用 | 示例(解码后) |
|---|---|---|
| Header(头部) | 声明 JWT 的 “类型” 和 “签名算法”(如 HS256=HMAC-SHA256) | {"alg":"HS256","typ":"JWT"}(表示用 HS256 算法签名,类型是 JWT) |
| Payload(载荷) | 存储非敏感的用户信息(如用户 ID、用户名、过期时间),也叫 “声明”(Claim) | {"userId":1,"userName":"Jack","exp":1716653602}(exp = 过期时间戳) |
| Signature(签名) | 对 Header+Payload 的哈希加密,防篡改(服务器用密钥验证签名是否被修改) | 用 Header 指定的 HS256 算法,结合服务器密钥(如my-secret-key)对前两段加密后的结果 |
¶2. JWT 的工作流程(和传统 Token 的区别)
以用户登录为例,JWT 的流程更 “轻量”:
- 用户登录:输入账号密码 → 服务器验证通过;
- 生成 JWT:服务器用密钥(如
my-secret-key)生成包含用户 ID、过期时间的 JWT(Header+Payload+Signature),返回给客户端; - 客户端存储:客户端把 JWT 存在
localStorage或 Cookie 中; - 后续请求:客户端每次请求都在 Header 里带 JWT(如
Authorization: Bearer <JWT>); - 服务器验证:服务器无需查数据库,直接做两件事:
- 用自己的密钥重新计算 JWT 的签名,对比客户端传来的签名是否一致(验证未被篡改);
- 检查 Payload 里的
exp字段(过期时间),确认 JWT 未过期;
- 验证通过:服务器直接从 Payload 中提取
userId,处理请求(如返回该用户的订单)。
¶3. JWT 的优缺点
¶优点:
- 无状态:服务器无需存储 JWT(传统 Token 需存数据库),减轻服务器压力,适合分布式系统(多台服务器共享密钥即可验证);
- 自包含:Payload 直接携带用户信息,减少数据库查询;
- 跨域友好:可在不同域名间传递(如前后端分离项目、第三方登录)。
¶缺点:
- 无法主动撤销:JWT 一旦生成,在过期前始终有效(除非服务器维护 “黑名单”,但会失去无状态优势);
- Payload 不加密:Header 和 Payload 是 Base64URL 编码(可解码),不能存敏感信息(如密码、手机号);
- 体积较大:相比短随机字符串,JWT 包含更多信息,会增加请求流量。
¶三、JWT 和 Token 的核心关系(总结)
用 “水果” 和 “苹果” 的类比最直观:
- Token = 水果(广义概念):指所有 “身份凭证”,包括随机字符串 Token、JWT、OAuth2 的 Access Token 等;
- JWT = 苹果(具体类别):是 Token 的一种标准化实现,特点是 “JSON 结构、自包含、无状态”。
两者的关键区别如下表:
| 维度 | Token(传统随机字符串) | JWT(JSON Web Token) |
|---|---|---|
| 数据结构 | 无结构(纯字符串) | 结构化(Header+Payload+Signature) |
| 信息存储 | 不包含用户信息(需查数据库) | 包含非敏感用户信息(Payload 可提取) |
| 服务器存储 | 需存储(数据库 / 缓存) | 无需存储(验证依赖密钥和签名) |
| 适用场景 | 简单系统、需主动撤销 Token 的场景 | 分布式系统、前后端分离、第三方登录 |
¶四、常见疑问
-
JWT 是加密的吗?
不是。Header 和 Payload 是 Base64URL 编码(可解码),只有 Signature 是加密的(防篡改)。若需加密 Payload,需额外用对称 / 非对称加密(如 AES、RSA)。 -
JWT 和 Session 有什么区别?
Session 是 “服务器存储用户状态”(SessionID 存在 Cookie,用户信息存在服务器),JWT 是 “客户端存储状态”(用户信息存在 JWT,服务器无状态)。 -
什么时候用 JWT,什么时候用传统 Token?
- 用 JWT:分布式系统、前后端分离、无需主动撤销 Token 的场景(如短期接口调用);
- 用传统 Token:需要主动踢用户下线、禁止登录的场景(如管理员禁用账号)。
我们需要先澄清 “JWT 不加密” 的核心误区,再系统对比 JWT 与其他 Token 实现,并最终分析现行主流方案的逻辑 ——JWT 的安全性不依赖 “加密存储数据”,而依赖 “防篡改 + 传输保护 + 安全设计”;主流方案则是 “JWT 作为 Access Token + 传统 Token 作为 Refresh Token” 的组合,本质是平衡 “无状态效率” 与 “安全可控性”。
¶一、核心澄清:JWT “不加密” 为何能保障传输安全?
JWT 的
Header和Payload确实是Base64URL 编码(非加密),任何人获取后都能解码查看内容,但这并不意味着 “不安全”。其安全性来自三层保障,核心目标是 “防止数据被窃取 + 防止数据被篡改”:¶1. 传输层:HTTPS 是 “第一道防线”(必须依赖)
JWT 本身不解决 “传输过程中被窃取” 的问题,但所有 Token(包括 JWT)的传输都必须依赖HTTPS:
- HTTPS 通过 SSL/TLS 协议对客户端与服务器之间的通信进行端到端加密,即使攻击者拦截了请求,也无法解密获取 JWT 内容;
- 若脱离 HTTPS,任何 Token(无论是 JWT 还是随机字符串)都会面临 “中间人攻击” 风险,这是传输层的基础安全要求,与 Token 类型无关。
¶2. 防篡改:签名机制是 “核心保障”(JWT 内置)
JWT 的
Signature(签名)是防止数据被篡改的关键,其原理如下:- 服务器生成 JWT 时,会用密钥(对称加密如 HS256,或非对称加密如 RS256)对
Header.Base64URL + "." + Payload.Base64URL进行哈希运算,得到签名; - 客户端携带 JWT 请求时,服务器会用相同的密钥 / 公钥重新计算前两段的哈希值,并与客户端传来的
Signature对比; - 若 JWT 的
Header或Payload被篡改(比如修改userId为他人 ID),重新计算的签名会与原签名完全不一致,服务器直接判定 JWT 无效。
关键结论:JWT 的 “不加密” 仅指 Payload 可解码,但签名机制确保了 “一旦篡改就会被发现”,从而保障数据的完整性。
¶3. 自身安全设计:规避敏感风险
JWT 通过 “不存储敏感信息” 和 “短期有效期” 进一步降低风险:
- 不存敏感数据:Payload 仅存储非敏感信息(如
userId、userName、exp过期时间),绝不包含密码、手机号、银行卡号等隐私数据(即使解码也无敏感信息可泄露); - 短期有效期:
exp字段强制设置短期过期时间(如 15 分钟),即使 JWT 被窃取,攻击者可用的窗口期也极短; - 可选加密 Payload:若需更强隐私保护,可额外对 Payload 用 AES 等算法加密(此时 Payload 解码后仍是密文),但会增加性能开销,非默认操作。
¶二、JWT 与其他 Token 实现方式的全面对比
Token 的核心是 “身份凭证”,除 JWT 外,常见实现包括传统随机字符串 Token(如 SessionID、自定义存库 Token)、OAuth2.0 Access Token(多形态)、Refresh Token等。我们从 6 个关键维度对比:
对比维度 JWT(JSON Web Token) 传统随机字符串 Token(如 SessionID、Redis 存 Token) OAuth2.0 Access Token(主流形态) Refresh Token(通常为随机字符串) 数据结构 结构化(Header.Payload.Signature,Base64URL 编码) 无结构(纯随机字符串,如 UUID、32 位哈希) 两种形态: 1. 随机字符串(如微信登录) 2. JWT(如 Google OAuth2) 无结构(长随机字符串,复杂度极高) 服务器存储 无需存储(验证依赖密钥 + 签名) 必须存储(数据库 / Redis 关联用户信息) 若为随机字符串则需存储;若为 JWT 则无需存储 必须存储(数据库 / Redis,关联用户 + 权限) 状态性 无状态(服务器不保存 Token 状态) 有状态(服务器需维护 Token 与用户的映射) 混合(依形态而定) 有状态(需维护有效性、黑名单) 防篡改机制 内置签名(HS256/RS256 等,篡改即无效) 无内置机制(需服务器验证是否存在 + 未被吊销) 同 JWT 或依赖存储验证 依赖存储验证(是否在库、未过期、未拉黑) 可撤销性 难(需维护 “黑名单”,失去无状态优势) 易(直接删除服务器存储的 Token 即可) 依形态而定(JWT 难,随机字符串易) 易(删除存储记录即可吊销) 核心适用场景 前后端分离、分布式系统、短期接口调用(如 API) 单体应用、需主动踢下线场景(如管理员禁用账号) 第三方登录(如微信 / QQ 登录)、开放平台 API 配合 Access Token,实现 “静默刷新” ¶三、现行主流 Token 实现方式:JWT(Access Token)+ 传统 Token(Refresh Token)
当前行业的绝对主流方案是 “双 Token 组合”:用 JWT 作为短期的
Access Token,用传统随机字符串作为长期的Refresh Token。这种方案并非单一 Token 实现,而是结合了两者的优势,规避各自的缺陷。¶1. 主流方案的工作流程
以用户登录为例,完整流程如下:
- 用户首次登录:输入账号密码 → 服务器验证通过;
- 生成双 Token:
- 生成
Access Token(JWT,有效期 15 分钟):包含userId、权限、exp过期时间,用服务器密钥签名; - 生成
Refresh Token(随机字符串,有效期 7 天):复杂度极高(如 64 位 UUID),存储到 Redis(关联userId、过期时间、设备信息);
- 生成
- 客户端存储:
Access Token:存在localStorage(前端)或内存(App),用于日常请求;Refresh Token:存在HttpOnly Cookie(防 XSS 攻击)或 App 安全存储,不允许前端直接操作;
- 日常请求:客户端用
Access Token在请求头中携带(如Authorization: Bearer <JWT>),服务器验证 JWT 签名和过期时间,直接从 Payload 提取userId处理请求; - Access Token 过期:
- 服务器返回 “Token 过期” 错误;
- 客户端用
Refresh Token向服务器请求 “刷新 Token” 接口;
- 刷新 Token:
- 服务器验证
Refresh Token(查 Redis 是否存在、未过期、未被拉黑); - 验证通过:生成新的
Access Token(JWT)和新的Refresh Token(旧的 Refresh Token 立即失效,避免复用),返回给客户端; - 验证失败(如 Refresh Token 过期 / 被拉黑):强制用户重新登录。
- 服务器验证
¶2. 为什么这是主流?—— 平衡 “效率、安全、体验”
这种组合方案能解决单一 Token 的所有痛点,完美适配现代系统(尤其是分布式、前后端分离、开放平台)的需求:
¶(1)兼顾 “无状态效率” 与 “安全可控性”
- JWT 作为
Access Token:无状态,服务器无需存储,多节点(如分布式服务、微服务)共享密钥即可验证,极大减轻服务器压力,适配分布式架构; - Refresh Token 作为 “安全兜底”:有状态(存 Redis),支持主动撤销(如用户登出、账号被禁用时,直接删除 Redis 中的 Refresh Token),解决 JWT “难撤销” 的致命缺陷。
¶(2)平衡 “安全性” 与 “用户体验”
- 短期
Access Token:即使被窃取,攻击者仅能使用 15 分钟,风险极低; - 长期
Refresh Token:存在 HttpOnly Cookie(防 XSS 攻击),且每次刷新都会生成新的,避免 “一次窃取终身可用”; - 静默刷新:
Access Token过期时,客户端用 Refresh Token 自动刷新,用户无需重新登录,体验流畅(如微信小程序、手机 App 的 “保持登录” 功能)。
¶(3)符合标准协议,生态成熟
- 该方案完全兼容OAuth2.0/OIDC(OpenID Connect) 协议(目前最主流的身份认证协议),几乎所有云服务(如阿里云、AWS)、第三方登录(如微信、Google、GitHub)都采用此方案;
- 开发成本低:主流框架(如 Spring Security、Node.js 的 jsonwebtoken 库)都内置了 JWT 生成 / 验证、Refresh Token 管理的工具,无需重复造轮子。
¶3. 其他方案的局限性(为何不是主流)
- 单一 JWT:无法主动撤销,若 JWT 被窃取,只能等其过期(即使用户改密码也无法踢下线),安全性不足;
- 单一传统随机字符串 Token:有状态,服务器需存储所有 Token,分布式系统中需同步存储(如 Redis 集群),性能开销大,且每次验证都需查库,效率低于 JWT;
- 单一 OAuth2.0 Access Token(随机字符串):依赖存储验证,效率低,且无法 “自包含” 用户信息,需额外查库获取权限,不适配高并发场景。
¶总结
- JWT 的安全性:不依赖 Payload 加密,而依赖HTTPS 传输防窃取、签名机制防篡改、短期有效期 + 不存敏感信息降风险;
- Token 对比核心:JWT 的优势是 “无状态、自包含”,缺陷是 “难撤销”;传统随机字符串 Token 的优势是 “易撤销”,缺陷是 “有状态、效率低”;
- 主流方案:JWT(Access Token)+ 传统随机字符串(Refresh Token),本质是用 JWT 的效率适配分布式架构,用 Refresh Token 的可控性弥补安全缺陷,同时兼顾用户体验,且符合 OAuth2.0/OIDC 标准,是当前行业的最优解。
是的,如果 JWT 被黑客成功截取(且未被篡改),黑客完全可以直接使用该 JWT 进行非法操作—— 只要 JWT 仍在有效期内,且未被服务端提前 “失效”(尽管 JWT 本身不支持主动失效)。
¶一、核心原因:JWT 的验证逻辑只看 “有效性”,不看 “持有者合法性”
JWT 的本质是一种 “自包含的身份凭证”,它的安全基础是 “签名防篡改”,而非 “防止泄露”。服务端验证 JWT 时,只会检查 3 件事,不会验证 “这个 JWT 是不是原持有者在用”:
- 签名有效性:验证 JWT 的签名(如 HS256、RS256 算法)是否由服务端信任的密钥生成,确保 JWT 未被篡改(这是用户问题中 “不篡改” 的前提,所以此步会通过);
- 时间有效性:检查 JWT 的
exp(过期时间)、nbf(生效时间)等字段,确保 JWT 在当前时间内有效; - 基础合法性:检查
iss(签发者)、aud(受众)等字段,确保 JWT 是服务端自己签发的、且面向当前应用。
只要这 3 步通过,服务端就会认为 “持有 JWT 的请求是合法的”—— 它无法区分 “原用户的正常请求” 和 “黑客截取后的非法请求”。
¶二、典型非法操作场景(不篡改 JWT)
假设用户 A 登录后,服务端签发了一个 JWT(包含 “用户 A 的 ID”“权限:查看 / 修改个人订单” 等信息),并通过网络传输给前端存储。如果黑客通过以下方式截取到该 JWT(如 XSS 攻击窃取前端存储的 JWT、网络嗅探未加密的 JWT),就能直接冒充用户 A 操作:
- 调用 “查看个人订单” 接口:在请求头中携带截取的 JWT,服务端验证通过后,返回用户 A 的订单数据;
- 调用 “修改收货地址” 接口:同样携带该 JWT,服务端会认为是用户 A 本人操作,执行地址修改;
- 若 JWT 包含更高权限(如管理员权限),黑客甚至能访问后台管理系统、删除数据等。
¶三、为什么 JWT 无法防止 “泄露后被滥用”?—— 源于 “无状态” 设计
JWT 的核心优势是 “无状态”:服务端不需要存储任何与 JWT 相关的信息(如 token 黑名单、用户与 token 的关联),只需通过密钥验证 JWT 本身即可。
但这个优势也带来了缺陷:服务端无法主动吊销已泄露的 JWT。一旦 JWT 泄露,在exp过期前,它始终是 “有效的凭证”,黑客可以反复使用 —— 除非服务端重启并更换签名密钥(但这会导致所有合法用户的 JWT 失效,代价极高)。
¶四、如何规避 “JWT 泄露” 的风险?(关键防护措施)
既然 JWT 泄露后会被滥用,核心防护思路是 “防止泄露” 和 “缩小泄露后的危害范围”,而非依赖 JWT 本身的 “防滥用” 能力:
- 强制使用 HTTPS 传输:HTTPS 会对整个请求(包括 JWT 所在的请求头)进行端到端加密,黑客无法通过网络嗅探截取明文 JWT(这是最基础、最关键的防护);
- 缩短 JWT 的有效期(
exp):将 JWT 的有效期设为短期(如 15 分钟、30 分钟),即使泄露,黑客能滥用的时间窗口也极小; - 结合 Refresh Token 机制:
- 用 “短期 JWT”(Access Token)作为日常接口调用的凭证;
- 用 “长期 Refresh Token”(存储在后端数据库,可主动失效)作为 “刷新 Access Token” 的凭证;
- 若 Access Token 泄露,黑客只能用 15 分钟;若 Refresh Token 泄露,服务端可直接在数据库中删除该 Refresh Token,使其无法再刷新 Access Token;
- 前端安全存储 JWT:避免将 JWT 存储在
localStorage(易被 XSS 攻击窃取),优先用HttpOnly + Secure的 Cookie(XSS 无法读取,且仅通过 HTTPS 传输); - 增加 CSRF 防护:若用 Cookie 存储 JWT,需配合 CSRF Token(防止黑客通过 “跨站请求” 利用用户的 JWT 发起操作);
- 敏感操作二次验证:对于核心操作(如转账、修改密码),即使 JWT 有效,也要求用户额外输入验证码 / 密码,进一步降低泄露风险。
¶总结
- 结论:不篡改的 JWT 被截取后,黑客可以直接用它进行非法操作,因为服务端只验证 JWT 的 “有效性”,不验证 “持有者合法性”;
- 本质矛盾:JWT 的 “无状态” 优势导致其无法主动失效,泄露后只能依赖 “有效期” 和 “外部防护” 控制风险;
- 核心防护:HTTPS 防传输泄露 + 短期有效期缩小危害 + Refresh Token 支持主动失效,是当前主流的安全方案。
要理解服务端如何通过数据库删除泄露的 Refresh Token,核心前提是:Refresh Token 是 “有状态存储” 的—— 它不像 JWT(Access Token)那样无需服务端存储,而是必须持久化到服务端数据库中,才能实现 “主动失效”。以下是具体的实现逻辑、操作步骤及关键注意事项:
¶一、前提:Refresh Token 的数据库存储设计(为什么能删除?)
要删除 Refresh Token,首先需要在数据库中明确 “存储什么” 和 “如何关联”。服务端通常会设计一张专门的refresh_token表,核心字段至少包含以下信息(用于定位和验证 Token):
| 字段名 | 类型 | 作用说明 |
|---|---|---|
id |
自增主键 | 唯一标识一条 Refresh Token 记录,用于内部操作 |
token |
VARCHAR(255) | Refresh Token 的原始字符串(或加密后的字符串,需确保唯一性),核心查询依据 |
user_id |
BIGINT | 关联的用户 ID,用于绑定 “Token 属于哪个用户”,支持 “批量失效某用户的所有 Token” |
expired_at |
DATETIME | Token 的过期时间(比 Access Token 长得多,如 7 天、30 天),用于验证时效性 |
created_at |
DATETIME | 创建时间,用于日志审计或清理过期 Token |
device_info |
VARCHAR(100) | (可选)设备标识(如手机型号、浏览器 UA),用于识别异常设备登录 |
is_revoked |
TINYINT(1) | (可选)是否已吊销标记(0 = 有效,1 = 已吊销),替代物理删除,便于审计 |
¶二、Refresh Token 泄露后,服务端的删除(失效)流程
当检测到 Refresh Token 泄露(如用户报告、系统检测到异常登录 IP),服务端通过 “定位记录→执行删除 / 标记” 的步骤,让泄露的 Token 立即失效。具体分为两种常见方式:
¶方式 1:物理删除(直接删除数据库记录)—— 最彻底的失效
这是最直接的方式:通过 Refresh Token 的唯一标识(如token字段或user_id + token),在数据库中删除对应的记录。
操作步骤:
-
定位目标记录:服务端接收 “失效请求”(如用户发起 “登出所有设备”、管理员后台触发 “吊销 Token”),获取关键查询条件 ——
- 若知道泄露的
token字符串:直接用WHERE token = '泄露的Refresh Token值'定位; - 若不知道具体
token,但知道用户 ID(如用户报告账号异常):用WHERE user_id = 123定位该用户的所有 Refresh Token(批量失效)。
- 若知道泄露的
-
执行删除 SQL:通过数据库操作(如 MySQL 的
1
DELETE
语句)删除记录:sql
1
2
3
4
5-- 单个Token失效(已知token值)
DELETE FROM refresh_token WHERE token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
-- 批量失效某用户的所有Token(用户报告账号异常)
DELETE FROM refresh_token WHERE user_id = 123; -
失效验证:当黑客拿着泄露的 Refresh Token 请求 “刷新 Access Token” 时,服务端会先查询
refresh_token表 —— 若未找到对应的记录,直接返回 “Token 无效”,拒绝刷新请求。
¶方式 2:逻辑标记(标记为 “已吊销”)—— 便于审计和追溯
部分场景下(如需要留存日志、避免误删后无法恢复),不直接删除记录,而是通过is_revoked字段标记为 “已吊销”。
操作步骤:
-
定位并更新记录:用
1
UPDATE
语句将目标 Token 的
1
is_revoked
设为 1(已吊销):sql
1
2
3UPDATE refresh_token
SET is_revoked = 1
WHERE token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; -
验证逻辑调整:服务端在验证 Refresh Token 时,除了检查
1
expired_at
(是否过期),还需额外检查
1
is_revoked = 0
(是否有效):sql
1
2
3
4
5-- 验证Refresh Token的SQL(需同时满足“未过期”和“未吊销”)
SELECT * FROM refresh_token
WHERE token = '用户提交的Refresh Token'
AND expired_at > NOW()
AND is_revoked = 0;若查询结果为空,说明 Token 已失效,拒绝刷新请求。
¶三、关键注意事项:确保删除操作的有效性和安全性
-
Refresh Token 必须加密存储:数据库中不能明文存储 Refresh Token(否则黑客若入侵数据库,可直接获取有效 Token)。需用不可逆加密算法(如 SHA-256)或对称加密(如 AES)存储,验证时需先对用户提交的 Token 做相同加密处理,再与数据库中的值比对。
-
添加数据库索引:在
token和user_id字段上建立索引(如INDEX idx_token (token),INDEX idx_user_id (user_id)),避免删除 / 查询时全表扫描,提高操作效率(尤其用户量较大时)。 -
处理并发请求:若黑客在 “删除操作执行前” 发起刷新请求,可能存在 “时间差漏洞”。可通过数据库事务(如
BEGIN TRANSACTION)确保 “查询 Token 有效性” 和 “生成新 Access Token” 的原子性,避免并发问题。 -
定期清理过期 Token:即使不主动删除,也要通过定时任务(如 Cron)清理
1
expired_at < NOW()
的过期记录,避免数据库表膨胀,影响查询性能:
sql
1
2-- 定时清理30天前过期的Refresh Token
DELETE FROM refresh_token WHERE expired_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
¶四、总结:为什么 “删除数据库中的 Refresh Token” 能解决泄露问题?
Refresh Token 的核心作用是 “申请新的 Access Token”—— 一旦它在数据库中被删除或标记为吊销,服务端就会认为该 Token “无效”,拒绝任何基于它的刷新请求。
这恰好弥补了 JWT(Access Token)“无法主动失效” 的缺陷:通过 “短期 Access Token + 可主动删除的 Refresh Token” 组合,既保留了 JWT 无状态的优势,又能在泄露时快速切断风险,是当前主流的安全方案。