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

React实现会话过期自动登出的方案求助

看起来你现在的问题是会话过期后没法自动触发登出,对吧?我看了你的代码,发现几个关键的点没处理到位,咱们一步步来修复:

一、先修复Cookie过期时间的问题

你当前设置Cookie过期的代码有个时间单位错误:

this.cookies.set("Token", response.data["access_token"], { path: "/", expires: new Date(Date.now() + 2592000) });

Date.now()返回的是毫秒数,而你写的2592000是秒数(30天),这会导致Cookie实际只存活约43分钟就过期。改成毫秒单位就好了:

// 2592000秒 × 1000 = 30天的毫秒数
this.cookies.set("Token", response.data["access_token"], { path: "/", expires: new Date(Date.now() + 2592000 * 1000) });
二、添加自动过期检测的定时器

你已经存了expires_in(Token的有效时长),但没利用它设置自动登出的定时器。在登录成功的回调里加上这段逻辑:

.then(response => {
  // ... 你的其他存储逻辑 ...

  // 清除之前可能存在的定时器,避免重复触发
  if (this.logoutTimer) clearTimeout(this.logoutTimer);

  // 提前30秒触发登出(给用户提示缓冲,可选)
  const expireTime = (response.data.expires_in - 30) * 1000;
  this.logoutTimer = setTimeout(() => {
    this.onLogout();
    Swal.fire({
      title: "会话过期",
      type: "info",
      text: "你的登录会话已过期,请重新登录",
      timer: 3000
    });
  }, expireTime);

  this.redirect();
})
三、页面初始化时检查Token是否已过期

现在你的redirect()只检查有没有Token,不校验是否过期。咱们需要结合登录时间和有效时长来判断:
首先,登录成功时把登录时间也存到localStorage:

ls.set("LoginTime", Date.now()); // 存储当前时间的毫秒数

然后修改redirect()方法:

redirect() {
  const token = ls.get("Token");
  const loginTime = ls.get("LoginTime");
  const expiresIn = ls.get("Expire in"); // 建议把key改成"ExpiresIn",避免空格带来的问题

  if (token) {
    // 计算Token是否已过期
    const isExpired = Date.now() > loginTime + (expiresIn * 1000);
    if (isExpired) {
      // 已过期,直接触发登出
      this.onLogout();
      Swal.fire({
        title: "会话过期",
        type: "info",
        text: "你的登录会话已过期,请重新登录",
        timer: 3000
      });
    } else {
      // 未过期,设置剩余时长的定时器
      const remainingTime = (loginTime + expiresIn * 1000) - Date.now();
      if (this.logoutTimer) clearTimeout(this.logoutTimer);
      this.logoutTimer = setTimeout(() => {
        this.onLogout();
        Swal.fire({
          title: "会话过期",
          type: "info",
          text: "你的登录会话已过期,请重新登录",
          timer: 3000
        });
      }, remainingTime);
      // 跳转到仪表盘,这里不需要强制刷新页面,React路由跳转足够
      this.props.history.push("/dashboard");
    }
  }
}
四、完善登出逻辑

在onLogout()里别忘了清除定时器和Cookie:

onLogout() {
  // 清除定时器,避免页面销毁后还触发
  if (this.logoutTimer) clearTimeout(this.logoutTimer);
  localStorage.clear();
  this.cookies.remove("Token", { path: "/" }); // 同步清除Cookie里的Token
  this.props.history.push("/");
  // 同样不需要强制刷新,路由跳转后会自动渲染登录页
}
五、额外优化建议
  • 把localStorage的key改成更规范的命名,比如token、refreshToken、loginTime,避免空格和大小写混乱
  • 如果后端支持刷新Token,可以在Token快过期时自动调用刷新接口,而不是直接登出,提升用户体验
  • 可以把定时器和过期检测逻辑封装成自定义Hook或者工具函数,方便在其他组件复用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:10:06