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

如何在Angular项目中实现会话到期前10秒弹出警告模态框功能

Angular 会话到期前10秒提醒模态框实现方案

前置准备

你需要提前准备好自定义的模态框组件,或者直接使用Angular Material、NG-ZORRO等组件库自带的对话框组件即可。

实现步骤

1. 封装JWT过期时间解析方法

首先在你的认证服务(通常是auth.service.ts)中新增JWT解析方法,提取token中的过期时间戳:

/**
 * 解析JWT获取过期时间戳(单位:毫秒)
 * @param token 存储的JWT字符串
 */
getTokenExpirationTime(token: string): number | null {
  if (!token) return null;
  try {
    // JWT格式为header.payload.signature,取第二段payload解码
    const payload = JSON.parse(atob(token.split('.')[1]));
    return payload.exp ? payload.exp * 1000 : null;
  } catch (error) {
    // 非法token直接返回空
    return null;
  }
}

2. 初始化会话倒计时定时器

在认证服务中新增定时器初始化方法,登录成功、刷新token成功后调用该方法即可自动计算弹框时间:

// 存储定时器ID,用于清除旧定时器
private sessionTimeoutTimer: any = null;

initSessionCountdown(): void {
  const token = localStorage.getItem('access_token');
  const expirationTime = this.getTokenExpirationTime(token);
  if (!expirationTime) return;

  // 计算距离提前10秒弹框的等待时长
  const notifyWaitTime = expirationTime - Date.now() - 10 * 1000;

  // 先清除已有定时器,避免重复触发
  if (this.sessionTimeoutTimer) {
    clearTimeout(this.sessionTimeoutTimer);
  }

  // 剩余有效期不足10秒直接弹提醒
  if (notifyWaitTime <= 0) {
    this.openExpireNotifyModal();
    return;
  }

  // 设置定时器到点弹提醒
  this.sessionTimeoutTimer = setTimeout(() => {
    this.openExpireNotifyModal();
  }, notifyWaitTime);
}

3. 实现到期提醒模态框逻辑

在认证服务中新增模态框唤起方法,支持续期、登出操作,10秒无操作自动登出:

// 需提前在构造函数注入对应对话框服务,比如Angular Material的MatDialog
constructor(private dialog: MatDialog, private router: Router) {}

openExpireNotifyModal(): void {
  const dialogRef = this.dialog.open(SessionExpireNotifyComponent, {
    disableClose: true, // 禁止点击空白关闭,强制用户操作
    width: '420px'
  });

  // 监听用户操作结果
  dialogRef.afterClosed().subscribe(operation => {
    if (operation === 'renew') {
      // 调用刷新token接口,成功后重置倒计时
      this.refreshToken().subscribe(res => {
        localStorage.setItem('access_token', res.access_token);
        this.initSessionCountdown();
      }, () => {
        // 刷新token失败直接走登出逻辑
        this.logout();
      })
    } else {
      this.logout();
    }
  });

  // 10秒无操作自动关闭模态框并登出
  setTimeout(() => {
    dialogRef.close();
    this.logout();
  }, 10 * 1000);
}

// 原有登出逻辑补充清除定时器
logout(): void {
  if (this.sessionTimeoutTimer) {
    clearTimeout(this.sessionTimeoutTimer);
  }
  localStorage.removeItem('access_token');
  this.router.navigate(['/login']);
}

4. 适配现有JWT拦截器

  • 拦截器检测到401时,先清除当前的会话定时器,再跳转登录页,避免重复弹框
  • 拦截器放行刷新token接口,避免刷新请求被拦截

可选优化点

  • 如果需要根据用户活跃状态自动续期,可以全局监听click、keydown等用户操作事件,触发时调用initSessionCountdown()重置倒计时
  • 模态框可以添加10秒倒数展示,提升用户感知

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:39:00