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

如何在JWT过期后自动发送并验证Refresh Token(Handlebars环境)

自动刷新JWT实现持久登录(Handlebars + Express)

问题现状

登录后生成的JWT有效期仅30秒,过期后刷新页面会被强制退出;已实现Refresh Token接口,但无法自动触发更新JWT Cookie,需要无手动操作的自动续期方案。

解决方案步骤

1. 修复后端Refresh Token接口Bug

当前refreshToken控制器存在多处错误,先修正:

  • 捕获JWT过期/无效的抛出异常
  • 修正req.cookie的拼写错误(应为req.cookies)
  • 移除无用的next()调用,改为返回明确响应
  • 优化Cookie清理逻辑

修正后的refreshToken控制器代码:

exports.refreshToken = async (req, res) => {
  const token = req.cookies.jwt;
  if (!token) {
    return res.status(401).send({ message: "未找到有效token" });
  }

  try {
    // 验证当前token(未完全过期即可通过)
    const user = jwt.verify(token, "helloworld");
    // 清理旧JWT Cookie
    res.clearCookie('jwt', { path: '/' });
    // 生成新JWT
    const newToken = jwt.sign({ _id: user._id.toString() }, 'helloworld', {
      expiresIn: "30s"
    });
    // 设置新JWT Cookie
    res.cookie("jwt", newToken, {
      path: '/',
      expires: new Date(Date.now() + 1000 * 30),
      httpOnly: true,
      sameSite: "lax"
    });
    return res.status(200).send({ message: "token已刷新" });
  } catch (err) {
    // 处理token过期/无效情况
    res.clearCookie('jwt', { path: '/' });
    return res.status(401).send({ message: "登录已过期,请重新登录" });
  }
}

同时修复verifyToken中间件的异常处理:

exports.verifyToken = async (req, res, next) => {
  const token = req.cookies.jwt;
  if (!token) {
    return res.status(401).send({ message: '未登录,请先登录' });
  }

  try {
    const user = jwt.verify(token, "helloworld");
    req.id = user._id;
    next();
  } catch (err) {
    res.clearCookie('jwt', { path: '/' });
    return res.status(401).send({ message: '登录已过期,请重新登录' });
  }
}

2. 配置Refresh Token路由

在路由文件中添加有效路由:

// 该接口无需verifyToken验证,用于刷新即将过期的token
router.get('/refresh-token', refreshToken);

3. 前端Handlebars页面添加自动刷新逻辑

在user.hbs页面底部添加脚本,定时调用刷新接口(提前5秒触发,避免token过期后请求失败):

<script>
// 每25秒触发一次token刷新
setInterval(async () => {
  try {
    const response = await fetch('/refresh-token', {
      method: 'GET',
      credentials: 'include' // 必须携带Cookie,后端才能读取JWT
    });
    if (response.status === 401) {
      // token完全过期,跳转登录页
      window.location.href = '/login';
    }
  } catch (err) {
    console.error('刷新token失败:', err);
  }
}, 25000);
</script>

4. 优化登录接口Cookie设置(可选)

若需调整初始token有效期,修改login控制器中的Cookie过期时间:

res.cookie("jwt", token, {
  path: '/',
  expires: new Date(Date.now() + 1000 * 30), // 保持30秒有效期
  httpOnly: true,
  sameSite: "lax"
});

关键注意事项

  • HttpOnly Cookie:由于JWT是HttpOnly属性,前端无法直接读取过期时间,固定间隔提前刷新是最稳妥的方案
  • 错误处理:若刷新请求返回401,说明token已完全过期,直接跳转登录页
  • 凭证携带:前端请求必须携带credentials: 'include',否则后端无法读取Cookie中的JWT

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 01:40:31