在NestJS其他模块/路由使用@UseGuards(AuthGuard)报错排查
问题:NestJS中使用@UseGuards(AuthGuard)指定路由认证时出错
问题背景
我在实现认证与授权系统,参考NestJS官方认证示例时发现,示例要么仅在Auth模块内配置认证,要么给全局所有路由加认证,还得配合@Public()装饰器。我的需求是:搭建好认证系统后,只通过@UseGuards(AuthGuard)就能指定需要认证的路由。
错误现象
在UsersController的路由上添加@UseGuards(AuthGuard)时,抛出以下错误:
throw new InvalidDecoratorItemException(decorator, item, context.name); ^ Error: Invalid guard passed to @UseGuards() decorator (AuthController).
尝试在UserModule中导入AuthModule,引发循环依赖;修复循环依赖后,装饰器的错误依然存在。
相关代码
auth.module.ts
import { JwtModule } from '@nestjs/jwt'; export const jwtConstant = "OANSOCOON!@NO!@#ON!@#ONN" @Module({ imports: [ UsersModule, JwtModule.register({ global: true, secret: jwtConstant, signOptions: { expiresIn: '30 days' } }) ], controllers: [AuthController], providers: [ AuthService ], exports: [AuthService] }) export class AuthModule { }
users.module.ts
@Module({ imports: [DatabaseModule], controllers: [UsersController], providers: [ { provide: 'users_model', useFactory: (connection: Connection) => connection.model('users', UserSchema), inject: ['DATABASE_CONNECTION'], }, UsersService, CaslAbilityFactory ], exports: [UsersService] }) export class UsersModule { }
users.controller.ts
@Controller('users') export class UsersController { constructor( private usersService: UsersService, private caslAbility: CaslAbilityFactory ) { } @Get() findAll() { return this.usersService.findAll() } // @UseGuards(AuthGuard) @Get(":id") findOnById(@Param('id') id: any, @Request() req) { console.log(req.user) return req.user return this.usersService.findById(id) } }
auth.controller.ts(补充)
import { AuthGuard } from './auth.guard'; @Controller('auth') export class AuthController { constructor( private authService: AuthService ) { } @HttpCode(HttpStatus.OK) @Post('login') signIn(@Body() signInDto: LoginArgDto) { return this.authService.signIn(signInDto.username, signInDto.password); } @UseGuards(AuthGuard) @Get('profile') profile(@Request() req) { return req.user } }
最终解决方案
放弃原有实现方式,基于Passport重新实现认证逻辑,参考NestJS官方Passport文档及GitHub相关示例完成开发,最终实现了仅通过@UseGuards(AuthGuard)指定需要认证路由的需求。
内容的提问来源于stack exchange,提问作者rick
相关产品推荐
相关产品推荐

