You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JWT令牌设置60秒过期却永不失效问题排查求助

问题根源及修复方案

1. JWT的iat字段使用毫秒级时间戳(核心错误)

在tokenManager.js的issueJWT和issueRefreshToken函数中,你手动设置了iat: Date.now(),但JWT标准里的iat(签发时间)要求是Unix时间戳(秒级),而Date.now()返回的是毫秒级时间戳。

这会导致JWT库计算过期时间时,把毫秒数当成秒数处理——比如当前毫秒时间是1718000000000,当成秒的话就是1718000000,相当于50多年后的时间,再加上60秒的有效期,令牌自然永远不会过期。

修复代码:

修改tokenManager.js中的payload部分,将iat改为秒级时间戳:

const issueJWT = (user) => {
  const expiresIn = 60;
  const payload = {
    sub: user.id,
    iat: Math.floor(Date.now() / 1000), // 替换Date.now()为秒级时间戳
  };
  const signedToken = jwt.sign(payload, PRIV_KEY, { expiresIn: expiresIn, algorithm: 'RS256' });
  return {
    token: "Bearer " + signedToken,
    expires: expiresIn
  };
};

const issueRefreshToken = (user) => {
  const expiresIn = '7d';
  const payload = {
    sub: user.id,
    iat: Math.floor(Date.now() / 1000), // 同样修改这里
  };
  const refreshToken = jwt.sign(payload, PRIV_KEY, { expiresIn: expiresIn, algorithm: 'RS256' });
  return refreshToken;
};

2. 优化中间件的错误处理(可选但推荐)

当前authMiddleware.js中,所有JWT验证错误都返回403,无法区分令牌过期、签名无效等不同情况,不利于调试和前端处理。可以修改为:

const authenticateJWT = (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (authHeader) {
    const token = authHeader.split(' ')[1];

    jwt.verify(token, PUB_KEY, { algorithms: ['RS256'] }, (err, user) => {
      if (err) {
        // 根据错误类型返回对应状态码
        if (err.name === 'TokenExpiredError') {
          return res.status(401).json({ message: '令牌已过期' });
        }
        return res.sendStatus(403); // 其他验证错误(如签名无效)返回403
      }
      req.user = user;
      next();
    });
  } else {
    res.sendStatus(401);
  }
};

3. 验证修复效果

  1. 重启服务器,重新获取JWT令牌
  2. 等待60秒后,用该令牌请求/info/getInfo接口,此时应该返回对应过期提示或状态码,证明过期逻辑生效。

内容的提问来源于stack exchange,提问作者joisberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 02:06:01