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

NestJS Passport AuthGuard无法验证有效Token,返回401或无效签名

问题:JWT手动验证正常但AuthGuard('jwt')返回401/无效签名

本地策略生成的Token,通过JwtService.verify(token)可正常验证并返回Payload,但使用@UseGuards(AuthGuard('jwt'))装饰器时,接口返回401 Unauthorized或Invalid signature,且无法获取req.user。


1. 手动验证代码(可正常返回Payload)

// auth.controller.ts
// ...
@Post(`/verify`)
async verify(@Request() req, @Headers() headers) {
  const authHeader = headers['authorization'] // 手动获取Authorization头值
  const token = authHeader.substring('Bearer '.length) // 移除Bearer前缀
  return this.jwtService.verify(token)
}

2. 使用AuthGuard的代码(无法获取req.user)

// auth.controller.ts
// ...
@UseGuards(AuthGuard('jwt'))
@Post(`/verify`)
async verify(@Request() req, @Headers() headers) {
  return(req.user)
}

3. JWT策略配置

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: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: `${process.env.JWT_SECRET}`,
    })
  }

  async validate(username: string, password: string) {
    return { username, password }
  }
}

4. AuthModule配置

// auth.module.ts
// ...

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt' }),
    MongooseModule.forFeature([
      {
        name: User.name,
        schema: UserSchema,
      },
    ]),
    JwtModule.register({
      secret: `${process.env.JWT_SECRET}`,
      signOptions: {
        expiresIn: '60d',
      },
    }),
  ],
  controllers: [AuthController],
  providers: [
    AuthService,
    UserService,
    HashService,
    LocalStrategy,
    JwtStrategy,
  ],
})
export class AuthModule {}

5. 自定义JwtAuthGuard尝试结果

自定义Guard的canActivate方法能正确读取并验证Token(可正常打印Payload),但handleRequest仍返回未授权,日志显示Jsonwebtokenerror: Invalid Signature:

// jwt-gaurd.ts
import { ExecutionContext, Injectable } from '@nestjs/common'
import { AuthGuard } from '@nestjs/passport'
import { JwtService } from '@nestjs/jwt'

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private jwtService: JwtService) {
    super({
      secret: `${process.env.JWT_SECRET}`,
      signOptions: {
        expiresIn: '60d',
      },
    })
  }

  async canActivate(context: ExecutionContext) {
    const request = context.switchToHttp().getRequest()
    const token = request.headers.authorization.split(' ')[1]
    try {
      const payload = await this.jwtService.verify(token)
      console.log(payload) // 可正常打印Payload
      super.canActivate(context)
      return true
    } catch (error) {
      return false
    }
  }

  async validate(payload: any) {
    return payload
  }

  handleRequest(err, user, info) {
    console.log(err, user, info)
    if (err || !user) {
      return err
    }
    return user
  }
}

已排查项

  • 多处提取的Token均能正常验证并获取Payload
  • 所有配置中的secret已核对一致
  • 依赖导入无问题

寻求解决该问题的可行方案。

内容的提问来源于stack exchange,提问作者another dolphin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:38:25