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

Angular应用中如何自动检测Bearer Token是否过期?

Angular中自动检测Bearer Token过期的可行方案

针对你的需求,以下是几个无需频繁轮询、能自动感知token过期的可行方案:

1. 基于Token过期时间设置单次定时器

这是替代轮询的最优方案——登录成功后直接解析Token里的过期时间,只设置一次定时器,到点自动触发登出,无多余性能消耗。

实现步骤:

  • 登录成功后,从JWT Token的Payload中提取exp字段(注意该字段是Unix时间戳,单位为秒,需转换为毫秒)
  • 计算当前时间到过期时间的差值,设置setTimeout
  • 若后续刷新了新Token,需清除旧定时器并重新设置
// auth.service.ts
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class AuthService {
  private expirationTimer: any;

  setAuthToken(token: string) {
    localStorage.setItem('token', token);
    // 清除旧定时器
    if (this.expirationTimer) clearTimeout(this.expirationTimer);
    
    // 解析Token中的过期时间
    const tokenPayload = JSON.parse(atob(token.split('.')[1]));
    const expirationMs = tokenPayload.exp * 1000;
    const timeToExpire = expirationMs - Date.now();

    // 设置单次定时器
    this.expirationTimer = setTimeout(() => {
      this.logout();
    }, timeToExpire);
  }

  logout() {
    localStorage.removeItem('token');
    // 补充登出逻辑:跳转登录页、清除用户状态等
    if (this.expirationTimer) {
      clearTimeout(this.expirationTimer);
      this.expirationTimer = null;
    }
  }
}

优势:

  • 无重复轮询,性能友好,代码逻辑简洁
  • 精准匹配Token过期时间,不会提前或延迟触发

2. 结合页面可见性事件做补充校验

浏览器切换标签页后,定时器可能因页面休眠出现延迟,通过监听visibilitychange事件,在用户切回页面时主动检查Token状态,避免显示过期的登录状态。

// auth.service.ts 补充代码
constructor() {
  document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'visible') {
      this.checkTokenValidity();
    }
  });
}

private checkTokenValidity() {
  const token = localStorage.getItem('token');
  if (!token) return;

  const tokenPayload = JSON.parse(atob(token.split('.')[1]));
  const expirationMs = tokenPayload.exp * 1000;
  
  if (Date.now() > expirationMs) {
    this.logout();
  } else {
    // 重置定时器,避免页面休眠导致的时间偏差
    if (this.expirationTimer) clearTimeout(this.expirationTimer);
    const timeToExpire = expirationMs - Date.now();
    this.expirationTimer = setTimeout(() => this.logout(), timeToExpire);
  }
}

3. 路由守卫做二次兜底

配合定时器使用,在用户切换路由时快速校验Token状态,作为自动登出的兜底手段,避免极端场景下的状态不一致。

// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(): boolean {
    const token = localStorage.getItem('token');
    if (!token) {
      this.router.navigate(['/login']);
      return false;
    }

    const tokenPayload = JSON.parse(atob(token.split('.')[1]));
    if (Date.now() > tokenPayload.exp * 1000) {
      this.authService.logout();
      this.router.navigate(['/login']);
      return false;
    }
    return true;
  }
}

在路由配置中为需要登录的路由添加该守卫即可。

关键注意事项

  • 前端解析的exp字段仅用于用户体验优化,Token最终有效性仍由后端API验证
  • 若应用存在Token刷新机制,刷新成功后必须调用setAuthToken更新定时器
  • 防范XSS风险:若Token存储在localStorage,需确保前端无XSS漏洞,避免攻击者篡改Token的exp字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:39:51