jose 中 JWTExpired 错误类完全指南:ERR_JWT_EXPIRED 的触发机制、属性与捕获实战
发布时间:2026/9/28 13:00:47 锦皓数字建站

网络安全认证鉴权后端【免费下载链接】joseJWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes项目地址https://gitcode.com/gh_mirrors/jo/jose点击查看免费下载JWTExpired 是 jose 在 JWT Claims Set 校验阶段抛出的专用错误子类专门用于标识 JWT 已过期或超出允许的最大 Token 年龄。本文以 JWTExpired 类文档 为核心结合 错误实现源码、Claims Set 校验源码 与仓库测试用例完整讲解该错误的继承体系、触发路径、全部实例属性以及基于稳定错误码ERR_JWT_EXPIRED的可靠捕获与统一处理方案帮助你写出对 Token 过期行为有精确掌控的鉴权代码。JWTExpired 在 jose 错误体系中的位置jose 将所有模块特定错误统一收敛在errors命名空间下可从主入口jose或子路径jose/errors导入见 src/index.ts 中import * as errors from ./util/errors.js的导出。JWTExpired 的继承与实现关系如下继承自通用基类JOSEError其code为ERR_JOSE_GENERIC定义于 src/util/errors.ts实现了JWTClaimValidationFailure接口因此具备claim、reason、payload三个结构字段与JWTClaimValidationFailed是并列关系而不是继承关系。这一点在官方文档中有明确提示JWTExpired 并不继承 JWTClaimValidationFailed因此对过期 JWT 执行err instanceof jose.errors.JWTClaimValidationFailed会得到false。若希望用一次判断覆盖两种 Claims Set 校验失败应使用联合类型 JWTClaimValidationError定义为JWTClaimValidationFailed | JWTExpired或利用code判别字段分别处理。该设计的完整说明见 JWTClaimValidationFailure 接口文档。何时抛出两条源码级触发路径JWTExpired 只在 Claims Set 校验阶段被抛出触发逻辑全部集中在validateClaimsSet()函数src/lib/jwt_claims_set.ts。该函数被jwtVerify使用文档和jwtDecrypt等在 JWS 签名验证或 JWE 解密完成之后调用这正是文档中强调Claims Set 校验发生在签名验证/解密流程之后的原因——错误对象上的payload一定是完整性已被验证的 Claims Set。源码中一共存在两处throw new JWTExpired(...)1.exp过期检查const exp validateNumericDate(payload, exp) if (exp ! undefined) { if (exp now - tolerance) { throw new JWTExpired(exp claim timestamp check failed, payload, exp, checkFailed) } }对应 src/lib/jwt_claims_set.ts当 JWT 携带exp且其 NumericDate 值 now - tolerance时抛出claim为expreason为check_failed。2.maxTokenAge最大 Token 年龄检查if (age - tolerance max) { throw new JWTExpired( iat claim timestamp check failed (too far in the past), payload, iat, checkFailed, ) }对应 src/lib/jwt_claims_set.ts当设置了maxTokenAge选项时若now - iat超出上限考虑clockTolerance容差同样抛出 JWTExpired此时claim为iatmessage 为iat claim timestamp check failed (too far in the past)。仓库测试对这两条路径均有断言可作对照test/jwt/verify.test.ts分别以{ exp: now }与{ iat: now - 31 }构造过期载荷并断言code: ERR_JWT_EXPIRED与对应 message见 test/jwt/verify.test.ts 与 test/jwt/verify.test.tstest/jwt/decrypt.test.ts也有完全一致的双路径覆盖见 test/jwt/decrypt.test.ts。此外属性测试 test/jwt/property.test.ts 还验证了捕获到的错误实例带有{ claim: exp, reason: check_failed }结构。实例属性详解JWTExpired 的每个实例都携带以下属性均源自 JWTExpired 类文档 与 类定义属性类型默认值/说明codestring恒为ERR_JWT_EXPIRED是模块稳定的错误码判别字段causeJWTClaimValidationFailure每个实例都携带的失败详情对象即{ claim, reason, payload }通过Error的cause选项挂载claimstring校验失败的 Claim 名称实际只会是exp或iatreasonstring失败原因码实际为check_failed源码常量const checkFailed check_failed见 src/lib/jwt_claims_set.tspayloadJWTPayload已解析的 JWT Claims Set。此阶段 JWS 签名或 JWE 结构的完整性已经验证通过但其余 JWT Claims 可能尚未校验从构造函数constructor(message, payload, claim unspecified, reason unspecified)src/util/errors.ts可以看出cause实际上是{ claim, reason, payload }的对象与实例自身的claim、reason、payload字段保持一致claim与reason的默认值unspecified仅在非本模块构造路径下出现。如何捕获 JWTExpired两种官方推荐方式文档给出了两种检查方式均能稳定识别该错误方式一通过稳定错误码判别if (err.code ERR_JWT_EXPIRED) { // 例如刷新 Token、引导重新登录、返回 401 }方式二通过 instanceof 判别if (err instanceof jose.errors.JWTExpired) { // ... }两种方式结合AnyJOSEError判别联合每个错误子类与其唯一的错误码配对见 src/util/errors.ts在 TypeScript 中还能获得自动类型收窄。源码注释提供了一个典型写法src/util/errors.tsfunction handle(err: jose.errors.AnyJOSEError) { switch (err.code) { case ERR_JWT_EXPIRED: console.log(err.payload) // 此处被收窄为 JWTExpired break case ERR_JWKS_MULTIPLE_MATCHING_KEYS: break } }统一处理 Claims Set 校验失败JWTClaimValidationError由于 JWTExpired 与 JWTClaimValidationFailed 是并列的两个类官方建议用 JWTClaimValidationError 联合类型配合code判别统一处理。该类型文档给出的类型守卫示例function isClaimValidationError(err: unknown): err is jose.errors.JWTClaimValidationError { return ( err instanceof jose.errors.JWTClaimValidationFailed || err instanceof jose.errors.JWTExpired ) }在处理Claims Set 校验失败这类语义一致、但来源不同的错误缺失必填 Claim、Claim 值不匹配、Token 已过期时这是一个非常实用的统一入口先收窄到JWTClaimValidationError再通过err.code ERR_JWT_EXPIRED分支出过期场景做差异化处理如刷新 Token其余分支处理普通校验失败。通过校验选项控制过期的判定边界JWTExpired 是否抛出、在何时抛出受 JWTVerifyOptions即 JWTClaimVerificationOptions中若干选项影响clockTolerance时钟偏移容差数字单位秒如5字符串会被解析如5 seconds、10 minutes、2 hours。判定公式为exp now - tolerance即容忍较短时间的过期偏差currentDate比较 NumericDate Claims 时使用的参考时间默认new Date()在测试中可用来模拟时间旅行maxTokenAge从iat起算的最大 Token 年龄设置后同时使iatClaim 成为必填项且触发第二条 JWTExpired 抛出路径requiredClaims必填 Claim 列表issuer、audience、subject各自对应的 Claim 也会自动成为必填。clockTolerance与maxTokenAge的字符串形式由secs()解析src/lib/jwt_claims_set.ts支持s、m、h、d、w、y及秒/分钟/小时等全称写法。测试 test/jwt/verify.test.ts 同时验证了maxTokenAge: 0与maxTokenAge: 0 seconds两种写法均抛出ERR_JWT_EXPIRED且测试注释明确说明Token 真正过期时即使设置有效容差仍会被拒绝见 test/jwt/verify.test.ts。完整实战签名、签发过期 Token 并精确捕获下面用一个可运行的完整流程演示如何触发并捕获 JWTExpired签发与校验 API 可参见 SignJWT 与 jwtVerifyimport * as jose from jose const secret new TextEncoder().encode( cc7e0d44fd473002f1c42167459001140ec6389b7353f8088f4d9a95f2f596f2, ) // 签发一个 30 秒后过期的 JWT const jwt await new jose.SignJWT({ urn:example:claim: true }) .setProtectedHeader({ alg: HS256 }) .setIssuedAt() .setIssuer(urn:example:issuer) .setAudience(urn:example:audience) .setExpirationTime(30s) .sign(secret) try { const { payload, protectedHeader } await jose.jwtVerify(jwt, secret, { issuer: urn:example:issuer, audience: urn:example:audience, clockTolerance: 5, // 允许 5 秒时钟偏移 }) console.log(protectedHeader, payload) } catch (err) { if (err instanceof jose.errors.JWTExpired) { // 官方推荐的属性访问claim 为 exp 或 iat console.error(JWT 过期过期 Claim: ${err.claim}) // payload 在此刻仍可读完整性已验证 console.error(已验证的 Claims Set:, err.payload) // 触发刷新逻辑或要求重新认证 } else if (err.code ERR_JWT_EXPIRED) { // 与 instanceof 等价的稳定错误码判别写法 } else { throw err } }这段代码同时演示了文档中的两种捕获方式先以instanceof jose.errors.JWTExpired精确匹配再以err.code ERR_JWT_EXPIRED作为稳定的替代判别并读取err.claim、err.payload等属性做差异化处理——这正是 JWTExpired 类在实际鉴权中间件、Token 刷新流程中最典型的应用场景。小结JWTExpired 是 jose 面向Token 过期这一高频业务场景提供的专用错误类型它通过稳定错误码ERR_JWT_EXPIRED与instanceof两种方式可被可靠识别在exp过期与maxTokenAge超龄两条源码路径上抛出src/lib/jwt_claims_set.ts实例携带claim、reason、payload、cause四个诊断字段且payload一定是完整性已验证的 Claims Set它与 JWTClaimValidationFailed 的并列关系意味着统一处理时应使用 JWTClaimValidationError 联合类型。理解这些细节能让你在鉴权代码中把过期与其他失败精确区分开写出行为可预期、便于测试与排查的错误处理逻辑。赞分享网络安全认证鉴权后端【免费下载链接】joseJWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes项目地址https://gitcode.com/gh_mirrors/jo/jose点击查看免费下载相关推荐jose 错误体系详解JOSEError 基类、错误码与实战捕获指南jose 错误体系详解JOSEError 基类、错误码与实战捕获指南 本文围绕 jose 库JWA / JWS / JWE / JWT / JWK / JW网络安全认证鉴权后端Dagger TypeScript SDK 错误处理详解ExecError 类的属性、源码与实战捕获Dagger TypeScript SDK 错误处理详解ExecError 类的属性、源码与实战捕获 本篇技术指南以 Dagger TypeScript SDDevOpsCI/CD后端CLI云原生Bluebird TimeoutError 完全指南超时错误的创建原理、.timeout 协作机制与实战捕获Bluebird TimeoutError 完全指南超时错误的创建原理、 .timeout 协作机制与实战捕获 导读 TimeoutError 是 Blueb后端上一篇推荐开源项目JINGO - 一个基于Git的Markdown Wiki引擎下一篇QQ 空间历史说说导出:3 步把 2014 年至今的动态存到本地创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。