jwt和token详解

要理解 JWTToken 的关系,核心是先明确 “Token 是广义概念,JWT 是 Token 的一种具体实现”—— 所有 JWT 都是 Token,但并非所有 Token 都是 JWT。下面分两部分详细拆解:

一、先搞懂:什么是 Token?

Token(令牌) 是服务器颁发给客户端的「身份凭证」,本质是一段无意义的随机字符串(或结构化数据),用于解决 “反复验证身份” 的问题。

Token 的核心作用:替代密码,简化认证

比如你登录 App 的流程:

  1. 首次登录:你输入账号密码 → 服务器验证通过后,生成一个唯一的 Token(如 a1b2c3d4...),返回给你的手机;
  2. 后续操作:你刷首页、看订单时,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 的流程更 “轻量”:

  1. 用户登录:输入账号密码 → 服务器验证通过;
  2. 生成 JWT:服务器用密钥(如my-secret-key)生成包含用户 ID、过期时间的 JWT(Header+Payload+Signature),返回给客户端;
  3. 客户端存储:客户端把 JWT 存在localStorage或 Cookie 中;
  4. 后续请求:客户端每次请求都在 Header 里带 JWT(如 Authorization: Bearer <JWT>);
  5. 服务器验证:服务器无需查数据库,直接做两件事:
    • 用自己的密钥重新计算 JWT 的签名,对比客户端传来的签名是否一致(验证未被篡改);
    • 检查 Payload 里的exp字段(过期时间),确认 JWT 未过期;
  6. 验证通过:服务器直接从 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 的场景 分布式系统、前后端分离、第三方登录

四、常见疑问

  1. JWT 是加密的吗?
    不是。Header 和 Payload 是 Base64URL 编码(可解码),只有 Signature 是加密的(防篡改)。若需加密 Payload,需额外用对称 / 非对称加密(如 AES、RSA)。

  2. JWT 和 Session 有什么区别?
    Session 是 “服务器存储用户状态”(SessionID 存在 Cookie,用户信息存在服务器),JWT 是 “客户端存储状态”(用户信息存在 JWT,服务器无状态)。

  3. 什么时候用 JWT,什么时候用传统 Token?

    • 用 JWT:分布式系统、前后端分离、无需主动撤销 Token 的场景(如短期接口调用);
    • 用传统 Token:需要主动踢用户下线、禁止登录的场景(如管理员禁用账号)。

    我们需要先澄清 “JWT 不加密” 的核心误区,再系统对比 JWT 与其他 Token 实现,并最终分析现行主流方案的逻辑 ——JWT 的安全性不依赖 “加密存储数据”,而依赖 “防篡改 + 传输保护 + 安全设计”;主流方案则是 “JWT 作为 Access Token + 传统 Token 作为 Refresh Token” 的组合,本质是平衡 “无状态效率” 与 “安全可控性”

    一、核心澄清:JWT “不加密” 为何能保障传输安全?

    JWT 的HeaderPayload确实是Base64URL 编码(非加密),任何人获取后都能解码查看内容,但这并不意味着 “不安全”。其安全性来自三层保障,核心目标是 “防止数据被窃取 + 防止数据被篡改”:

    1. 传输层:HTTPS 是 “第一道防线”(必须依赖)

    JWT 本身不解决 “传输过程中被窃取” 的问题,但所有 Token(包括 JWT)的传输都必须依赖HTTPS

    • HTTPS 通过 SSL/TLS 协议对客户端与服务器之间的通信进行端到端加密,即使攻击者拦截了请求,也无法解密获取 JWT 内容;
    • 若脱离 HTTPS,任何 Token(无论是 JWT 还是随机字符串)都会面临 “中间人攻击” 风险,这是传输层的基础安全要求,与 Token 类型无关。

    2. 防篡改:签名机制是 “核心保障”(JWT 内置)

    JWT 的Signature(签名)是防止数据被篡改的关键,其原理如下:

    1. 服务器生成 JWT 时,会用密钥(对称加密如 HS256,或非对称加密如 RS256)对Header.Base64URL + "." + Payload.Base64URL进行哈希运算,得到签名;
    2. 客户端携带 JWT 请求时,服务器会用相同的密钥 / 公钥重新计算前两段的哈希值,并与客户端传来的Signature对比;
    3. 若 JWT 的HeaderPayload被篡改(比如修改userId为他人 ID),重新计算的签名会与原签名完全不一致,服务器直接判定 JWT 无效。

    关键结论:JWT 的 “不加密” 仅指 Payload 可解码,但签名机制确保了 “一旦篡改就会被发现”,从而保障数据的完整性。

    3. 自身安全设计:规避敏感风险

    JWT 通过 “不存储敏感信息” 和 “短期有效期” 进一步降低风险:

    • 不存敏感数据:Payload 仅存储非敏感信息(如userIduserNameexp过期时间),绝不包含密码、手机号、银行卡号等隐私数据(即使解码也无敏感信息可泄露);
    • 短期有效期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. 主流方案的工作流程

    以用户登录为例,完整流程如下:

    1. 用户首次登录:输入账号密码 → 服务器验证通过;
    2. 生成双 Token:
      • 生成Access Token(JWT,有效期 15 分钟):包含userId、权限、exp过期时间,用服务器密钥签名;
      • 生成Refresh Token(随机字符串,有效期 7 天):复杂度极高(如 64 位 UUID),存储到 Redis(关联userId、过期时间、设备信息);
    3. 客户端存储:
      • Access Token:存在localStorage(前端)或内存(App),用于日常请求;
      • Refresh Token:存在HttpOnly Cookie(防 XSS 攻击)或 App 安全存储,不允许前端直接操作;
    4. 日常请求:客户端用Access Token在请求头中携带(如Authorization: Bearer <JWT>),服务器验证 JWT 签名和过期时间,直接从 Payload 提取userId处理请求;
    5. Access Token 过期:
      • 服务器返回 “Token 过期” 错误;
      • 客户端用Refresh Token向服务器请求 “刷新 Token” 接口;
    6. 刷新 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(随机字符串):依赖存储验证,效率低,且无法 “自包含” 用户信息,需额外查库获取权限,不适配高并发场景。

    总结

    1. JWT 的安全性:不依赖 Payload 加密,而依赖HTTPS 传输防窃取签名机制防篡改短期有效期 + 不存敏感信息降风险
    2. Token 对比核心:JWT 的优势是 “无状态、自包含”,缺陷是 “难撤销”;传统随机字符串 Token 的优势是 “易撤销”,缺陷是 “有状态、效率低”;
    3. 主流方案JWT(Access Token)+ 传统随机字符串(Refresh Token),本质是用 JWT 的效率适配分布式架构,用 Refresh Token 的可控性弥补安全缺陷,同时兼顾用户体验,且符合 OAuth2.0/OIDC 标准,是当前行业的最优解。

是的,如果 JWT 被黑客成功截取(且未被篡改),黑客完全可以直接使用该 JWT 进行非法操作—— 只要 JWT 仍在有效期内,且未被服务端提前 “失效”(尽管 JWT 本身不支持主动失效)。

一、核心原因:JWT 的验证逻辑只看 “有效性”,不看 “持有者合法性”

JWT 的本质是一种 “自包含的身份凭证”,它的安全基础是 “签名防篡改”,而非 “防止泄露”。服务端验证 JWT 时,只会检查 3 件事,不会验证 “这个 JWT 是不是原持有者在用”:

  1. 签名有效性:验证 JWT 的签名(如 HS256、RS256 算法)是否由服务端信任的密钥生成,确保 JWT 未被篡改(这是用户问题中 “不篡改” 的前提,所以此步会通过);
  2. 时间有效性:检查 JWT 的exp(过期时间)、nbf(生效时间)等字段,确保 JWT 在当前时间内有效;
  3. 基础合法性:检查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 本身的 “防滥用” 能力:

  1. 强制使用 HTTPS 传输:HTTPS 会对整个请求(包括 JWT 所在的请求头)进行端到端加密,黑客无法通过网络嗅探截取明文 JWT(这是最基础、最关键的防护);
  2. 缩短 JWT 的有效期(exp:将 JWT 的有效期设为短期(如 15 分钟、30 分钟),即使泄露,黑客能滥用的时间窗口也极小;
  3. 结合 Refresh Token 机制:
    • 用 “短期 JWT”(Access Token)作为日常接口调用的凭证;
    • 用 “长期 Refresh Token”(存储在后端数据库,可主动失效)作为 “刷新 Access Token” 的凭证;
    • 若 Access Token 泄露,黑客只能用 15 分钟;若 Refresh Token 泄露,服务端可直接在数据库中删除该 Refresh Token,使其无法再刷新 Access Token;
  4. 前端安全存储 JWT:避免将 JWT 存储在localStorage(易被 XSS 攻击窃取),优先用HttpOnly + Secure的 Cookie(XSS 无法读取,且仅通过 HTTPS 传输);
  5. 增加 CSRF 防护:若用 Cookie 存储 JWT,需配合 CSRF Token(防止黑客通过 “跨站请求” 利用用户的 JWT 发起操作);
  6. 敏感操作二次验证:对于核心操作(如转账、修改密码),即使 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),在数据库中删除对应的记录。
操作步骤

  1. 定位目标记录:服务端接收 “失效请求”(如用户发起 “登出所有设备”、管理员后台触发 “吊销 Token”),获取关键查询条件 ——

    • 若知道泄露的token字符串:直接用 WHERE token = '泄露的Refresh Token值' 定位;
    • 若不知道具体token,但知道用户 ID(如用户报告账号异常):用 WHERE user_id = 123 定位该用户的所有 Refresh Token(批量失效)。
  2. 执行删除 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;
  3. 失效验证:当黑客拿着泄露的 Refresh Token 请求 “刷新 Access Token” 时,服务端会先查询refresh_token表 —— 若未找到对应的记录,直接返回 “Token 无效”,拒绝刷新请求。

方式 2:逻辑标记(标记为 “已吊销”)—— 便于审计和追溯

部分场景下(如需要留存日志、避免误删后无法恢复),不直接删除记录,而是通过is_revoked字段标记为 “已吊销”。
操作步骤

  1. 定位并更新记录:用

    1
    UPDATE

    语句将目标 Token 的

    1
    is_revoked

    设为 1(已吊销):sql

    1
    2
    3
    UPDATE refresh_token 
    SET is_revoked = 1
    WHERE token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
  2. 验证逻辑调整:服务端在验证 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 已失效,拒绝刷新请求。

三、关键注意事项:确保删除操作的有效性和安全性

  1. Refresh Token 必须加密存储:数据库中不能明文存储 Refresh Token(否则黑客若入侵数据库,可直接获取有效 Token)。需用不可逆加密算法(如 SHA-256)或对称加密(如 AES)存储,验证时需先对用户提交的 Token 做相同加密处理,再与数据库中的值比对。

  2. 添加数据库索引:在tokenuser_id字段上建立索引(如INDEX idx_token (token), INDEX idx_user_id (user_id)),避免删除 / 查询时全表扫描,提高操作效率(尤其用户量较大时)。

  3. 处理并发请求:若黑客在 “删除操作执行前” 发起刷新请求,可能存在 “时间差漏洞”。可通过数据库事务(如BEGIN TRANSACTION)确保 “查询 Token 有效性” 和 “生成新 Access Token” 的原子性,避免并发问题。

  4. 定期清理过期 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 无状态的优势,又能在泄露时快速切断风险,是当前主流的安全方案。