技术指南

JWT Token 过期问题排查:从原理到实战的完整解决方案

JWT Token 过期是前后端开发中最常见的认证问题之一。本文将系统讲解 JWT Token 过期的核心原理、 4种最常见的过期原因、标准化的 6 步排查流程,以及刷新 Token 与 Access Token 的协同策略。 通过真实案例分析和详细的数据示例,帮助你快速定位并解决 JWT Token 过期问题。 文章配套 JWT 解析工具JSON 格式化工具, 方便你在排查过程中快速解码和分析 Token 数据。

JWT Token 过期时间排查示意图

什么是 JWT Token 过期:exp 字段详解

JWT(JSON Web Token)是一种基于 RFC 7519 标准的轻量级认证方案,其过期机制完全依赖 Payload 中的 exp(Expiration Time)字段。 根据 RFC 7519 规范exp 字段是一个数值型声明(NumericDate), 表示 token 必须在此时间之前被接受。该值以 Unix 时间戳的秒为单位,即从 1970-01-01T00:00:00Z UTC 开始计算的秒数。

一个典型的 JWT Token 过期场景是这样的:当服务端接收到请求时,会先解析 token 的 Payload, 然后比较当前服务器时间和 exp 字段的值。 如果当前时间大于 exp 值, 服务端就会拒绝该请求并返回 401 Unauthorized 错误。 除了 exp 字段外, 还有两个与时间相关的关键字段需要关注: iat(Issued At,签发时间) 和 nbf(Not Before,生效时间)。 这三个字段共同构成了 JWT Token 的完整生命周期管理机制。

时间字段的实际数据示例

为了更好地理解这些时间字段,我们来看一个真实的 JWT Payload 示例:

{
  "sub": "user_12345",
  "iat": 1704067200,
  "exp": 1704153600,
  "nbf": 1704067260
}

在这个示例中:iat 值为 1704067200, 对应 2024-01-01 00:00:00 UTC;exp 值为 1704153600, 对应 2024-01-02 00:00:00 UTC,表示该 token 的有效期为 24 小时; nbf 值为 1704067260, 表示 token 在签发后 60 秒才生效。你可以使用我们的 JWT 解析工具 快速查看这些时间字段的实际含义。

4 种最常见的 JWT Token 过期原因分析

在实际开发中,我们总结了导致 JWT Token 过期问题的 4 大类原因。每一类都有其特定的表现特征和解决方案。

原因一:时间戳单位错误(秒 vs 毫秒)

这是最常见的新手错误。JavaScript 的 Date.now() 返回的是毫秒级时间戳,而 JWT 标准要求的是秒级时间戳。如果在生成或验证 token 时混淆了这两个单位, 就会出现严重的偏差。例如,当前毫秒级时间戳约为 1704067200000,如果误将其作为秒级时间戳使用, 相当于将 token 的过期时间设置到了公元 53994 年,这显然是不合理的。 反之,如果将秒级时间戳当作毫秒级来处理,token 会立即过期。 正确的做法是在 JavaScript 中使用 Math.floor(Date.now() / 1000) 来获取秒级时间戳。

原因二:时钟偏差问题(Clock Skew)

时钟偏差是指客户端和服务端之间的系统时间不一致。在分布式系统中,即使配置了 NTP 时间同步, 也可能存在几秒到几分钟的时间差。根据 jwt.io 官方文档的建议, 验证时应考虑时钟偏差,通常设置为 30 秒到 5 分钟的容错范围。 例如,如果服务端时间比客户端快了 2 分钟,一个在客户端看来还有 1 分钟才过期的 token, 到达服务端时可能已经过期了。解决方法是在验证逻辑中加入 clockTolerance 参数, 允许一定范围内的时间偏差。

原因三:刷新 Token 逻辑缺陷

许多应用采用 Access Token + Refresh Token 的双 token 架构。Access Token 有效期较短(通常 15-30 分钟), Refresh Token 有效期较长(通常 7-30 天)。常见的问题包括:前端没有正确实现自动刷新逻辑, 导致在 Access Token 过期后仍然使用旧 token 发起请求;Refresh Token 本身已过期但前端没有引导用户重新登录; 或者多个标签页同时发起刷新请求,导致后一个刷新操作覆盖前一个,造成 token 不一致。 正确的实现应该在前端请求拦截器中检测 401 响应,然后自动使用 Refresh Token 获取新的 Access Token, 并重试原请求。

原因四:缓存与状态同步问题

浏览器的 localStorage、sessionStorage、Cookie 以及各种 HTTP 缓存都可能导致 token 状态不一致。 典型场景包括:用户在一个标签页登出,但其他标签页仍在使用缓存的旧 token; Service Worker 缓存了包含旧 token 的 API 响应;或者浏览器扩展修改了请求头中的 Authorization 字段。 此外,移动端 App 的 token 存储在本地,如果用户清除应用数据或更换设备, 也会出现 token 丢失或过期的问题。建议在关键操作前增加 token 有效性检查, 并实现跨标签页的状态同步机制(如使用 BroadcastChannel API)。

标准排查流程:6 步法从解码到验证

当遇到 JWT Token 过期问题时,按照以下 6 个步骤进行系统性排查,可以快速定位问题根源。

1

解码 Token 检查时间字段

使用 JWT 解析工具 或 jwt.io 对 token 进行 Base64 解码,重点检查 expiatnbf 三个时间字段的值是否合理。 注意区分秒级和毫秒级时间戳。

2

对比客户端与服务端时间

分别获取客户端和服务器端的当前时间戳,计算两者之间的时间差。如果差异超过 30 秒, 说明存在时钟偏差问题。可以通过访问服务端的 /api/time 接口或检查响应头中的 Date 字段来获取服务端时间。

3

验证网络请求中的实际 Token

打开浏览器开发者工具的 Network 标签,检查失败的请求头中 Authorization 字段的值。 确认发送的 token 是否与预期的 token 一致,是否存在 token 被截断、编码错误或被其他中间件修改的情况。

4

检查 Refresh Token 流程

确认 Refresh Token 是否有效且未过期。检查前端拦截器是否正确捕获 401 错误并触发刷新流程。 查看刷新接口的响应是否返回了新的 Access Token,以及新 token 是否被正确存储和使用。

5

分析服务端日志与错误信息

查看服务端的应用日志,找到具体的错误堆栈和错误代码。常见的错误信息包括 "jwt expired"、"token is expired"、"signature verification failed" 等。 这些信息可以帮助判断问题是出在 token 过期、签名验证还是其他环节。

6

排除缓存与并发问题

清除浏览器缓存和 Cookie 后重新测试。检查是否有多个标签页或窗口同时操作同一账号。 使用隐私/无痕模式进行测试,排除浏览器扩展和第三方脚本的干扰。

刷新 Token 与 Access Token 协同策略

在现代 Web 应用中,单一 token 的设计已经无法满足安全性和用户体验的双重需求。 Access Token + Refresh Token 的双 token 架构成为业界标准实践。 这种架构的核心思想是将短期有效的 Access Token 用于日常 API 访问, 将长期有效的 Refresh Token 仅用于获取新的 Access Token。

推荐的 Token 有效期配置

Token 类型推荐有效期存储位置用途说明
Access Token15 - 30 分钟内存(Memory)用于 API 请求认证
Refresh Token7 - 30 天HttpOnly Cookie仅用于刷新 Access Token
ID Token (OIDC)1 小时内存(Memory)包含用户身份信息

自动刷新的最佳实践

前端应实现基于拦截器的自动刷新机制。当 API 请求返回 401 状态码时, 拦截器应自动暂停后续请求,使用 Refresh Token 调用刷新接口获取新的 Access Token, 然后重试原始请求。需要注意的是,必须处理并发刷新的情况: 当多个请求同时收到 401 响应时,应确保只发起一次刷新请求, 其他请求等待刷新完成后再重试。可以使用 Promise 缓存或请求队列来实现这一机制。 此外,如果 Refresh Token 本身也过期了,应立即清除本地认证状态并跳转到登录页面。

实战案例:一个真实的前后端时间不一致问题

以下是我们团队在实际项目中遇到的一个典型案例,希望能为你提供参考。

问题描述

用户反馈在每天凌晨 0 点左右频繁出现"Token 已过期"的错误提示, 但用户明明刚刚登录不到 10 分钟。这个问题在生产环境持续了一周, 影响了约 15% 的活跃用户。

排查过程

首先,我们使用 JWT 解析工具 解码了用户提供的 token,发现 exp 字段显示的过期时间是当天 23:59:59 UTC+8, 而用户报告问题的时间是 00:01:32 UTC+8。接着我们检查了服务端日志, 发现服务端记录的当前时间比客户端快了约 3 分钟。 进一步调查发现,部署在 AWS 上的某台 EC2 实例由于 NTP 同步失败, 系统时间出现了漂移,最终导致了这个间歇性的 token 过期问题。

解决方案

我们采取了三个措施:(1)修复了 NTP 配置,启用 chronyd 并配置多个可靠的时间源; (2)在 JWT 验证逻辑中加入了 5 分钟的 clockTolerance 容错参数; (3)增加了健康检查接口,定期监控各服务实例的系统时间偏差。 经过这些调整后,类似的 token 过期投诉降为零。

FAQ:常见问题解答

解码 JWT 是否会验证签名?

不会。在线解码工具(如 jwt.io)只是对 token 进行 Base64 解码并格式化显示 Payload 内容, 这个过程完全不涉及签名验证。要验证 token 的完整性和真实性,必须使用密钥进行 cryptographic 验证。 因此,解码通过的 token 不一定是合法有效的 token,它可能已被篡改或伪造。 你可以参考 MDN Web Crypto API 文档 了解如何在浏览器端进行签名验证。

前后端时间不一致如何解决?

首先确认时间偏差的大小。如果是几秒到几分钟的差异,可以在服务端验证时加入 clockTolerance 参数 (推荐 30 秒到 5 分钟)。如果偏差较大(超过 5 分钟),需要检查服务器的 NTP 时间同步配置。 对于 Docker 容器或 Kubernetes Pod,确保容器能够正确同步宿主机的时间。 前端也可以通过 API 获取服务端时间作为基准,而不是完全依赖本地系统时间。

多标签页打开会导致 Token 冲突吗?

会。当用户在同一浏览器的多个标签页中使用同一账号时,每个标签页都可能独立维护自己的 token 状态。 如果一个标签页触发了 token 刷新,其他标签页可能仍在使用旧的 token,导致请求失败。 解决方案是使用 BroadcastChannel API 或 localStorage 事件监听来实现跨标签页的 token 状态同步。 当一个标签页更新 token 时,通知其他标签页同步更新本地存储的 token 值。

如何设置合理的 Token 过期时间?

这需要在安全性、用户体验和服务器性能之间取得平衡。Access Token 建议设置为 15-30 分钟, 这样即使 token 泄露,攻击者的利用窗口也很小。Refresh Token 可以设置为 7-30 天, 但应该支持主动撤销(如用户修改密码时失效所有 refresh token)。 对于高安全级别的应用(如金融系统),Access Token 可以缩短至 5-10 分钟, 并配合 MFA 多因素认证使用。具体时长应根据业务场景和安全需求综合评估确定。

总结

JWT Token 过期问题的排查需要系统性的方法论。从理解 exp 字段的本质开始, 到掌握 4 类常见原因的分析技巧,再到运用 6 步标准化排查流程, 最后结合 Refresh Token 的协同策略,形成完整的知识体系。 记住,大多数 token 过期问题并非真正的"过期",而是时间计算错误、时钟偏差、 刷新逻辑缺陷或缓存不一致导致的假象。

当你下次遇到 JWT Token 过期问题时,不妨先使用我们的 JWT 解析工具 快速解码 token 查看时间字段,再配合本文的排查流程逐步定位问题。 如果你还需要处理 JSON 数据的格式化,可以使用 JSON 格式化工具 来辅助分析复杂的 API 响应数据。

张明 · Tools321 技术编辑

发布于 2025-12-08 · 更新于 2026-05-25

Token已过期怎么办?JWT过期与刷新方案解析

什么是 JWT 与 Token 过期?

JWT(JSON Web Token)是一种紧凑的令牌格式,常用于用户登录后的身份认证。服务端在签发时写入过期时间(exp),客户端在有效期内携带它访问接口。一旦超过这个时间点,令牌即被视为已失效,再次请求会收到拒绝。理解它的失效机制,是解决「Token已过期」类问题的第一步。

当接口返回未授权状态时,多数情况下并非程序出错,而是令牌到期或被服务端作废。下面从原因、设计、排查到安全实践,系统梳理应对思路,并配合 JWT 解析工具快速定位具体字段。

为什么 Token 会过期?

  • 到达过期时间:签发时设置的 exp 已小于当前时间,这是最常见的原因。
  • 服务端主动作废:用户退出登录、修改密码或触发安全策略后,旧令牌被加入黑名单。
  • 时间不同步:服务器或客户端系统时钟偏差较大,导致校验时误判为已过期。
  • 令牌被篡改:签名校验失败会直接判定为无效,表现形式与过期类似。

Access Token 与 Refresh Token

Access Token

短期有效,用于访问受保护接口,过期后需重新获取。

Refresh Token

有效期更长,用于在 Access Token 过期后换取新的令牌,避免频繁登录。

Token 过期排查步骤

  1. 读取报错信息:确认接口返回的是 401 还是其他状态码,以及是否带有过期相关提示。
  2. 解析令牌内容:用 JWT 解析工具查看 exp、iat 等字段,核对过期时间是否确实已过。
  3. 检查时钟同步:对比客户端与服务端的系统时间,排除时差导致的误判。
  4. 触发刷新流程:若存在 Refresh Token,按设计调用刷新接口获取新的 Access Token。
  5. 确认作废策略:排查服务端是否因退出登录或安全策略主动作废了令牌。

安全与续期最佳实践

  • 合理设置有效期:Access Token 不宜过长,降低泄露风险。
  • 无感刷新:在即将过期前静默换取新令牌,提升用户体验。
  • 安全存储:避免在本地存储中明文放置长期令牌,优先使用更安全的存储方式。
  • 异常监控:对频繁的过期与刷新失败进行告警,及时发现攻击行为。

JWT 的结构与校验原理

JWT 由头部、载荷与签名三部分组成,以点号分隔。服务端通过密钥对签名进行校验,任何对内容的篡改都会使签名不匹配。过期判断依赖载荷中的 exp 字段。

注:客户端解析仅用于调试查看,真正的有效性校验必须由服务端完成,切勿在客户端信任未经验证的令牌。

常见问题

Token 已过期(token is expired)是什么意思?

表示服务端在校验时发现令牌的过期时间已早于当前时间,因此拒绝本次请求。这通常是正常的时效控制,而非程序故障,按刷新流程获取新令牌即可。

JWT 过期了怎么办?怎样快速续期?

如果系统设计了 Refresh Token,客户端应在检测到过期后自动调用刷新接口换取新的 Access Token;若没有刷新机制,则需要用户重新登录获取令牌。

接口返回 401 一定是 Token 过期吗?

不一定。401 表示未授权,可能由令牌缺失、签名错误、被服务端作废或权限不足等多种原因引起。需要解析令牌并检查服务端日志来确认具体原因。

本地时间和服务器时间不一致会导致误判过期吗?

会。若客户端或服务器时钟偏差较大,服务端按自身时间校验 exp 时就可能把实际未过期的令牌判为过期。保持系统时间同步(如开启网络校时)可以减少这类问题。

为什么刷新后旧 Token 仍能使用?

如果服务端没有实现作废名单(黑名单)或版本号机制,旧令牌在过期前依然有效。对于安全性要求较高的场景,建议在退出登录或修改密码时主动将其加入黑名单。

可以用工具查看 Token 里的内容吗?

可以。将令牌粘贴到 JWT 解析工具中即可查看头部与载荷中的 exp、iat、用户标识等字段,方便排查是否真的过期或内容是否符合预期。注意解析仅用于查看,校验仍需服务端完成。

本文内容仅供技术参考,具体实现请结合你的后端框架与安全规范。