如何在Angular客户端实现JWT Token的有效性校验?
Angular客户端实现RS512签名JWT的有效性校验
1. 安装JWT处理依赖
推荐使用jose库(轻量且原生支持RS512算法,和你服务端的签名算法匹配),执行安装命令:
npm install jose
2. 放置公钥文件
把服务端提供的PEM格式公钥放到项目的assets目录下(比如命名为public-key.pem),公钥必须是标准格式:
-----BEGIN PUBLIC KEY----- 你的公钥内容 -----END PUBLIC KEY-----
3. 封装校验服务
创建一个AuthService统一处理Token校验逻辑:
import { Injectable } from '@angular/core'; import { readPublicKey, jwtVerify } from 'jose'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class AuthService { private publicKey: CryptoKey | null = null; constructor(private http: HttpClient) { // 初始化加载公钥 this.loadPublicKey(); } private async loadPublicKey(): Promise<void> { const pemContent = await this.http.get('/assets/public-key.pem', { responseType: 'text' }).toPromise(); this.publicKey = await readPublicKey(pemContent, 'RS512'); } async validateToken(token: string): Promise<boolean> { // 确保公钥已加载完成 if (!this.publicKey) { await this.loadPublicKey(); } try { // 校验签名及默认声明(比如过期时间exp) const { payload } = await jwtVerify(token, this.publicKey, { algorithms: ['RS512'] }); // 额外确认过期状态(可选,jwtVerify已默认检查) const isExpired = Date.now() > payload.exp! * 1000; return !isExpired; } catch (err) { // 签名无效、Token过期、格式错误都会触发异常 console.error('Token校验失败:', err); return false; } } }
4. 在项目中使用校验逻辑
比如在路由守卫里校验用户登录状态:
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) {} async canActivate(): Promise<boolean> { const token = localStorage.getItem('auth-token'); if (!token) { this.router.navigate(['/login']); return false; } const isValid = await this.authService.validateToken(token); if (!isValid) { this.router.navigate(['/login']); return false; } return true; } }
备选方案:使用@auth0/angular-jwt
如果你习惯用这个库,也可以按以下方式配置:
- 安装依赖:
npm install @auth0/angular-jwt
- 在
AppModule中配置:
import { NgModule } from '@angular/core'; import { JwtModule } from '@auth0/angular-jwt'; import { HttpClientModule } from '@angular/common/http'; export function tokenGetter() { return localStorage.getItem('auth-token'); } @NgModule({ imports: [ HttpClientModule, JwtModule.forRoot({ config: { tokenGetter: tokenGetter, algorithms: ['RS512'], // 直接传入公钥字符串,或通过HTTP请求加载 publicKey: `-----BEGIN PUBLIC KEY----- 你的公钥内容 -----END PUBLIC KEY-----` } }) ] }) export class AppModule {}
- 使用
JwtHelperService校验:
import { JwtHelperService } from '@auth0/angular-jwt'; // 在组件/服务中注入后使用 const helper = new JwtHelperService(); const isTokenValid = !helper.isTokenExpired(token) && helper.verifyToken(token);
关键注意点
- 公钥是公开资源,放在客户端没问题,但要确保项目通过HTTPS部署,防止公钥被篡改。
- 必须指定算法为
RS512,和服务端保持一致,否则校验会直接失败。 - 除了签名校验,一定要确认Token的过期时间,避免使用已失效的Token。
内容的提问来源于stack exchange,提问作者MarieSpeak
相关产品推荐
相关产品推荐

