在日常开发过程中,我们经常需要处理 Token 过期的情况,以前的处理方式通常是后端在返回 Token 时一并返回一个过期时间,前端保存此过期时间,在之后的交互中以此判断该 Token 是否已过期。

由于我之前只做前端开发,并没有深入去了解 Token 的相关知识,直到开始接触后端开发后才发现,Token 本身就可以携带过期时间。

在 JWT Handbook 中讲到了两个字段 expiat,分别对应 Token 的过期时间和生成时间,两者的单位都是,Handbook 中对两者的解释如下:

  • exp: from the word expiration (time). A number representing a specific date and time in the format “seconds since epoch” as defined by POSIX6 . This claims sets the exact moment from which this JWT is considered invalid. Some implementations may allow for a certain skew between clocks (by considering this JWT to be valid for a few minutes after the expiration date).
  • iat: from issued at (time). A number representing a specific date and time (in the same format as exp and nbf) at which this JWT was issued.

因此,仅通过 exp 这个字段,我们就可以直接从 Token 本身进行过期判断,而不需要额外的信息。

示例

后端在生成 Token 时指定过期时间:

const jwt = require('jsonwebtoken');
const token = jwt.sign({uid: "abcdf123", isVip: false, username: "Jack"}, {
  expiresIn: `30d`,
  algorithm: "RS512"
});


 


在前端我们可以使用 jwt-decode 来对 Token 进行解码:

import jwt_decode from "jwt-decode";

const decoded = jwt_decode(token);

console.log(decoded);


 


得到的解码信息如下:

/*{
  uid: "abcdf123",
  username: "Jack",
  isVip: false,
  exp: 1393286893,
  iat: 1393268893
}*/




 


exp 的值乘以 1000 以转换成毫秒数,与当前时间的毫秒数做对比,即可判断 Token 是否过期:

if (decoded.exp * 1000 < Date.now()) {
  console.log("token expired!")
} else {
  console.log("token not expired!")
}
 




虽然 exp 的单位为秒,换算为毫秒后精度上会有一点损失,但这点损失算不上问题。

结语

相比额外存储过期时间,显然直接从 Token 本身进行判断更加安全。

最近更新:
作者: MeFelixWang