实时JWT token过期管理:如何实现页面空闲时也可检测token过期
JWT全局过期检测实现方案
核心实现思路
你当前的校验逻辑属于请求触发的被动校验,要实现空闲状态也能检测,只需要主动监听token的过期时间点即可,两种常用可落地的方案如下:
方案一:精准延时触发方案(优先推荐)
JWT本身就携带了过期时间戳exp字段,不需要轮询,只需要在每次拿到新token(登录/刷新token)时,计算出到过期时间的等待时长,设置一次性定时器触发过期逻辑即可:
- 新增全局定时器变量,每次设置新定时器前先清空旧定时器,避免重复触发
- 应用初始化、页面刷新时,先检查本地是否存在有效token,存在则重新计算等待时长设置定时器
- 该方案性能开销几乎为0,触发时机精准,适合绝大部分场景
方案二:低频率轮询校验方案
如果存在服务端主动作废token的业务场景(比如后台踢人、用户改密码),可以搭配短间隔轮询做补充校验:
- 每隔1~5分钟调用一次你已有的
isTokenExpired()方法校验token状态 - 轮询间隔不要设置过短,避免不必要的性能消耗
- 可以和方案一结合,在token临近过期前再缩小轮询间隔,提升检测准确性
原有逻辑兼容
你拦截器中的现有过期校验逻辑不需要删除,可作为兜底方案,避免页面休眠、定时器异常导致的漏判问题,形成双重保障。
参考实现代码
// 可以把这段逻辑封装到SessionService或Auth服务中 private tokenExpireTimer: number | null = null; // 登录/刷新token/应用初始化时调用该方法 initTokenExpireListener(): void { // 清空已有定时器 if (this.tokenExpireTimer) { window.clearTimeout(this.tokenExpireTimer); } const token = this.sessionService.getToken(); if (!token) return; // 解析JWT payload获取过期时间 try { const payload = JSON.parse(atob(token.split('.')[1])); const expireTimeMs = payload.exp * 1000; const waitTime = expireTimeMs - Date.now(); if (waitTime <= 0) { // 已经过期直接执行处理逻辑 this.handleTokenExpire(); return; } // 设置定时器到点触发 this.tokenExpireTimer = window.setTimeout(() => { this.handleTokenExpire(); }, waitTime); } catch (e) { // token解析失败直接判定无效 this.handleTokenExpire(); } } // 统一的token过期处理逻辑,和拦截器逻辑保持一致 handleTokenExpire(): void { this.toastrService.warning( '您将被重定向到登录页面', '会话已过期', { timeOut: 10000, } ); localStorage.clear(); sessionStorage.clear(); window.location.href = '/login'; }
如果你用的是Angular框架,可以把这个初始化方法注册到APP_INITIALIZER中,应用启动时自动执行初始化。
内容的提问来源于stack exchange,提问作者Man24
相关产品推荐
相关产品推荐

