Angular 8中检查JWT令牌是否过期的方法及示例代码请求
在Angular 8中检查JWT令牌是否过期的几种实用方法
在Angular 8里检查JWT令牌是否过期,我总结了几个实用的方案,每个都附上可直接运行的代码示例,你可以根据项目场景灵活选择:
方法一:手动解析JWT Payload检查过期时间
JWT的Payload部分包含exp字段(Unix时间戳,单位为秒),我们可以手动解码这个字段,和当前时间对比判断是否过期。这种方法不需要额外依赖,适合轻量场景。
代码示例:AuthService服务
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class AuthService { constructor() { } // 检查令牌是否过期 isTokenExpired(token: string): boolean { if (!token) return true; try { const payload = this.decodeJwtPayload(token); // 将exp转换为毫秒,和当前时间对比 const expirationTime = payload.exp * 1000; const currentTime = Date.now(); return currentTime > expirationTime; } catch (error) { // 解析失败则视为令牌无效/过期 return true; } } // 获取本地存储的令牌 getToken(): string | null { return localStorage.getItem('authToken'); } // 私有方法:解码JWT的Payload部分 private decodeJwtPayload(token: string): any { const payloadPart = token.split('.')[1]; // 处理JWT特有的Base64编码替换(-代替+,_代替/) const standardBase64 = payloadPart.replace(/-/g, '+').replace(/_/g, '/'); // 补全Base64所需的等号 const paddedBase64 = standardBase64.padEnd( standardBase64.length + ((4 - standardBase64.length % 4) % 4), '=' ); const decodedPayload = atob(paddedBase64); return JSON.parse(decodedPayload); } }
在组件中使用
import { Component, OnInit } from '@angular/core'; import { AuthService } from './auth.service'; @Component({ selector: 'app-auth-check', template: ` <div class="status"> <span *ngIf="isTokenValid" style="color: green;">✅ 令牌未过期</span> <span *ngIf="!isTokenValid" style="color: red;">❌ 令牌已过期,请重新登录</span> </div> ` }) export class AuthCheckComponent implements OnInit { isTokenValid: boolean = false; constructor(private authService: AuthService) { } ngOnInit(): void { const token = this.authService.getToken(); this.isTokenValid = token ? !this.authService.isTokenExpired(token) : false; } }
方法二:使用@auth0/angular-jwt库简化操作
如果项目里经常处理JWT,推荐使用专门的库来封装逻辑,它会自动处理解码、过期检查等细节,还能帮你在请求头自动添加令牌。
步骤1:安装兼容Angular 8的版本
npm install @auth0/angular-jwt@4 --save
步骤2:配置JwtModule
在你的AuthModule或AppModule中配置:
import { NgModule } from '@angular/core'; import { JwtModule } from '@auth0/angular-jwt'; // 定义令牌获取函数 export function tokenGetter() { return localStorage.getItem('authToken'); } @NgModule({ imports: [ JwtModule.forRoot({ config: { tokenGetter: tokenGetter, allowedDomains: ['your-api-domain.com'], // 允许添加令牌的API域名 disallowedRoutes: ['your-api-domain.com/login'] // 不需要令牌的路由 } }) ] }) export class AuthModule { }
步骤3:在服务中使用JwtHelperService
import { Injectable } from '@angular/core'; import { JwtHelperService } from '@auth0/angular-jwt'; @Injectable({ providedIn: 'root' }) export class AuthService { private jwtHelper = new JwtHelperService(); constructor() { } // 检查令牌是否过期 isTokenExpired(): boolean { const token = localStorage.getItem('authToken'); return this.jwtHelper.isTokenExpired(token); } }
方法三:在HTTP拦截器中全局检查过期
如果想在所有API请求前统一检查令牌状态,过期则自动跳转到登录页,HTTP拦截器是最佳选择。
代码示例:AuthInterceptor拦截器
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { AuthService } from './auth.service'; import { Router } from '@angular/router'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private authService: AuthService, private router: Router) {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { const token = this.authService.getToken(); // 检查令牌是否过期 if (token && this.authService.isTokenExpired(token)) { localStorage.removeItem('authToken'); this.router.navigate(['/login']); return throwError(() => new Error('令牌已过期,请重新登录')); } // 令牌有效则添加到请求头 if (token) { request = request.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); } // 处理请求返回的401错误(令牌无效/过期) return next.handle(request).pipe( catchError(error => { if (error.status === 401) { localStorage.removeItem('authToken'); this.router.navigate(['/login']); } return throwError(() => error); }) ); } }
注册拦截器
在AppModule的providers中添加:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { AuthInterceptor } from './auth.interceptor'; @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ] }) export class AppModule { }
内容的提问来源于stack exchange,提问作者Pinnu
相关产品推荐
相关产品推荐

