如何在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
相关产品推荐
相关产品推荐

