jsonwebtoken (Node.js)JWT 库
错误信息
jwt not active
jsonwebtoken (Node.js) — NotBeforeError from jwt.verify()
含义
这是 jsonwebtoken 的 `NotBeforeError`:令牌的 `nbf`(not before)声明晚于验证方的当前时间,因此令牌尚未生效。错误的 `date` 属性保存的是令牌开始生效的时刻。签名已经检查过,没有问题。
原因
验证方的时钟慢于颁发者的时钟
常见颁发者通常把 `nbf` 设为签发时间。如果验证方机器的时钟慢了几秒或几分钟,刚签发的令牌在时钟追上之前都会验证失败——看起来就像登录后立刻出现的间歇性故障。
令牌签名时设置了 notBefore 延迟
偶见`jwt.sign(payload, key, { notBefore: "5m" })` 会有意签发一个稍后才生效的令牌。提前使用它时,拒绝它是正确的结果。
nbf 以毫秒表示
罕见NumericDate 是自纪元(epoch)以来的秒数。手工构造的载荷如果写入 `nbf: Date.now()`,只有在遥远的未来才会生效。
修复方法
- 1.
允许少量时钟偏差
`clockTolerance`(单位为秒)同时作用于 `nbf` 和 `exp`。把它控制在一分钟以内,并在两台机器上用 NTP 解决真正的时钟漂移。
js jwt.verify(token, publicKey, { algorithms: ["ES256"], clockTolerance: 30, // seconds; applies to nbf and exp }); - 2.
测算令牌提前了多久
比较 `err.date` 与验证方的时钟。相差几秒说明是时钟偏差;恰好等于 `notBefore` 延迟说明令牌使用得太早;相差数千年说明存在毫秒单位错误。
js try { jwt.verify(token, publicKey, { algorithms: ["ES256"] }); } catch (err) { if (err.name === "NotBeforeError") { const early = (err.date.getTime() - Date.now()) / 1000; console.warn("token becomes valid in", early.toFixed(1), "s"); } throw err; }