NestJS 和 Passport-local : AuthGuard('local') validate() 永远不会被调用

Gig*_*igs 5 passport-local nestjs nestjs-passport nestjs-jwt

我已一步步遵循官方 Nest 文档(https://docs.nestjs.com/security/authenticationvalidate() ),但在使用@AuthGuard('local')@AuthGuard(LocalAuthGuard)登录操作时无法调用方法。

如果我不使用该保护装饰器,则一切都会按预期工作(但我需要使用它来将我的令牌添加到请求对象中)。

auth.controller.ts

  @UseGuards(AuthGuard('local')) // or AuthGuard(LocalAuthGuard)
  @Post('login')
  async login(
    @Request() req
  ) {
    const { access_token } = await this.authService.login(req.user);
    return access_token;
  }
}
Run Code Online (Sandbox Code Playgroud)

本地策略.ts

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super({ usernameField: 'email' });
  }

  async validate(email: string, password: string): Promise<any> { // class is constructed but this method is never called
    const user: UserDto = await this.authService.login({
      email,
      password,
    });
    
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
Run Code Online (Sandbox Code Playgroud)

auth.module.ts

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: "bidon", 
      signOptions: {
        expiresIn: '3600',
      },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService, PassportModule, JwtModule],
  controllers: [AuthController],
})
export class AuthModule {}
Run Code Online (Sandbox Code Playgroud)

PS:我已经阅读了所有与堆栈溢出相关的帖子(例如:NestJS 的 Passport 本地策略“验证”方法从未调用),但它们没有帮助我。

小智 6

我发现如果我们不传递emailpassword,并且两者的值都是错误的,警卫将响应未经授权的消息。问题是如果未定义,如何确保在运行保护逻辑之前对必填字段进行验证,换句话说,前端不会将其传递给服务器。如果我们添加@Body() data: loginDto控制器方法,它不会验证主体参数。

\n

为了解决这个问题,我在文件中添加了一些验证代码local.guard.ts。这是我的项目中的代码:

\n
import { HttpException, HttpStatus, Injectable, UnauthorizedException } from "@nestjs/common";\nimport { AuthGuard } from "@nestjs/passport";\n\n@Injectable()\nexport class LocalAuthGuard extends AuthGuard(\'local\') {\n  handleRequest(err, user, info, context, status) {\n    const request = context.switchToHttp().getRequest();\n    const { mobile, password } = request.body;\n    if (err || !user) {\n      if (!mobile) {\n        throw new HttpException({ message: \'\xe6\x89\x8b\xe6\x9c\xba\xe5\x8f\xb7\xe4\xb8\x8d\xe8\x83\xbd\xe4\xb8\xba\xe7\xa9\xba\' }, HttpStatus.OK);\n      } else if (!password) {\n        throw new HttpException({ message: \'\xe5\xaf\x86\xe7\xa0\x81\xe4\xb8\x8d\xe8\x83\xbd\xe4\xb8\xba\xe7\xa9\xba\' }, HttpStatus.OK);\n      } else {\n        throw err || new UnauthorizedException();\n      }\n    }\n    return user;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n