如何程序化检查JWT令牌过期并自动登出用户?解决token.expired未定义问题
解决方案:Angular中判断JWT令牌过期并实现自动登出
问题根源
后端返回的JWT是纯字符串格式,本身并不自带expired属性,直接访问该属性自然会显示undefined。要判断令牌是否过期,需要先解析JWT的Payload部分,取出其中的过期时间戳后与当前时间对比。
方法1:手动解析JWT并判断过期
自己实现解析逻辑,无需额外依赖:
- 编写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); }
- 在组件中使用解析结果判断过期
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库简化操作,它封装了解析、过期判断等常用功能:
- 安装依赖
npm install @auth0/angular-jwt
- 在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 {}
- 在组件中判断过期并登出
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
相关产品推荐
相关产品推荐

