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

如何程序化检查JWT令牌过期并自动登出用户?解决token.expired未定义问题

解决方案:Angular中判断JWT令牌过期并实现自动登出

问题根源

后端返回的JWT是纯字符串格式,本身并不自带expired属性,直接访问该属性自然会显示undefined。要判断令牌是否过期,需要先解析JWT的Payload部分,取出其中的过期时间戳后与当前时间对比。


方法1:手动解析JWT并判断过期

自己实现解析逻辑,无需额外依赖:

  1. 编写JWT解析函数
parseJwt(token: string): any {
  // 拆分JWT的三段式结构,取出中间的Payload部分
  const base64Url = token.split('.')[1];
  // 处理URL安全的Base64编码(替换-为+,_为/)
  const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
  // Base64解码并转成JSON对象
  const jsonPayload = decodeURIComponent(
    atob(base64)
      .split('')
      .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
      .join('')
  );
  return JSON.parse(jsonPayload);
}
  1. 在组件中使用解析结果判断过期
import { Router } from '@angular/router';

constructor(private router: Router) {}

ngOnInit(): void {
  const token = localStorage.getItem('authToken'); // 假设令牌存在localStorage中
  if (token) {
    const decodedToken = this.parseJwt(token);
    // 将当前时间转成秒级Unix时间戳(JWT的exp字段单位为秒)
    const currentUnixTime = Math.floor(Date.now() / 1000);
    const isExpired = decodedToken.exp < currentUnixTime;

    if (isExpired) {
      // 执行自动登出逻辑:清除令牌、跳转登录页
      localStorage.removeItem('authToken');
      this.router.navigate(['/login']);
    }
  }
}

方法2:使用成熟JWT库(推荐)

使用@auth0/angular-jwt库简化操作,它封装了解析、过期判断等常用功能:

  1. 安装依赖
npm install @auth0/angular-jwt
  1. 在AppModule中配置
import { JwtModule } from '@auth0/angular-jwt';

// 定义令牌获取函数
export function tokenGetter() {
  return localStorage.getItem('authToken');
}

@NgModule({
  imports: [
    JwtModule.forRoot({
      config: {
        tokenGetter: tokenGetter,
        allowedDomains: ['你的后端API域名'], // 替换为实际域名
        disallowedRoutes: ['你的后端API域名/login'] // 登录接口无需令牌校验
      }
    })
  ]
})
export class AppModule {}
  1. 在组件中判断过期并登出
import { JwtHelperService } from '@auth0/angular-jwt';
import { Router } from '@angular/router';

constructor(private jwtHelper: JwtHelperService, private router: Router) {}

ngOnInit(): void {
  const token = localStorage.getItem('authToken');
  if (token && this.jwtHelper.isTokenExpired(token)) {
    // 自动登出逻辑
    localStorage.removeItem('authToken');
    this.router.navigate(['/login']);
  }
}

进阶:实时监听令牌过期(避免仅初始化检查)

上面的方法仅在组件初始化时检查一次,如果用户停留在页面超过令牌有效期,不会自动触发登出。可以通过定时器实现实时监听:

import { Router, OnDestroy } from '@angular/router';

export class YourComponent implements OnInit, OnDestroy {
  private expireTimer: any;

  constructor(private router: Router) {}

  ngOnInit(): void {
    this.startExpirationMonitor();
  }

  startExpirationMonitor(): void {
    const token = localStorage.getItem('authToken');
    if (!token) return;

    const decodedToken = this.parseJwt(token);
    // 计算距离过期剩余的毫秒数
    const timeUntilExpire = (decodedToken.exp * 1000) - Date.now();

    // 设置定时器,到期后执行登出
    this.expireTimer = setTimeout(() => {
      localStorage.removeItem('authToken');
      this.router.navigate(['/login']);
    }, timeUntilExpire);
  }

  // 组件销毁时清除定时器,避免内存泄漏
  ngOnDestroy(): void {
    if (this.expireTimer) {
      clearTimeout(this.expireTimer);
    }
  }

  // 复用之前的parseJwt函数
  parseJwt(token: string): any {
    // ... 实现代码
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 16:13:13