在Nest的@UseGuards(JwtAuthGuard)前提取Bearer令牌中Token字符串的方法
问题描述
前端基于Next.js用fetch发起请求,代码如下:
async function fetchProfile() { const res = await fetch(`http://localhost:5000/api/v1/users/1`, { method: "GET", headers: { "Content-Type": "application/json", "token": "Bearer " + localStorage.getItem("token") } }) }
后端NestJS控制器代码:
@UseGuards(JwtAuthGuard) @Get(':id') findOne(@Param('id', ParseIntPipe) params: { id: number }, @Req() req) { console.log(req); return this.userService.findOne(params.id, req); }
注释掉@UseGuards(JwtAuthGuard)时,控制台能拿到完整的token请求头:
token: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJlbWFpbCI6ImF6YWQuaG9zc2VpbjIzQGdtYWlsLmNvbSIsImlhdCI6MTY5MDA5NzE4OX0._ncc6g71l8mrmgNTUUybhPRG696tX8sE3GAL-Fs_Kzo',
需求是在JwtAuthGuard执行前,从Bearer格式的令牌中提取纯Token字符串。
解决方案
NestJS的JwtAuthGuard默认依赖JwtStrategy,而默认策略只会从Authorization头提取Bearer令牌。现在token存在自定义的token头里,需要自定义策略来适配:
1. 编写自定义JWT策略
在Auth模块下创建jwt.strategy.ts,修改token提取逻辑:
import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor() { super({ jwtFromRequest: (req) => { const tokenHeader = req.headers.token; if (!tokenHeader) return null; // 分割Bearer前缀和token主体,提取纯token const [bearer, token] = tokenHeader.split(' '); return bearer === 'Bearer' ? token : null; }, ignoreExpiration: false, secretOrKey: process.env.JWT_SECRET, // 替换为你的JWT密钥 }); } async validate(payload: any) { // 验证成功后,返回的对象会被挂载到req.user上 return { userId: payload.id, email: payload.email }; } }
2. 在Auth模块中注册策略
确保Auth模块的providers数组包含自定义策略:
import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; import { PassportModule } from '@nestjs/passport'; import { JwtStrategy } from './jwt.strategy'; import { AuthService } from './auth.service'; @Module({ imports: [ PassportModule, JwtModule.register({ secret: process.env.JWT_SECRET, signOptions: { expiresIn: '60m' }, }), ], providers: [AuthService, JwtStrategy], exports: [JwtModule], }) export class AuthModule {}
3. 保持原有Guard使用
控制器上的@UseGuards(JwtAuthGuard)无需修改,JwtAuthGuard会自动使用自定义策略完成token提取和验证。
这样配置后,JwtAuthGuard执行前,策略会自动从token头中提取Bearer后的纯token字符串,顺利完成JWT验证流程。
内容的提问来源于stack exchange,提问作者Hossein Azad
相关产品推荐
相关产品推荐

