'NestJS and passport-local : AuthGuard('local') validate() never get called
I've followed the official Nest doc (https://docs.nestjs.com/security/authentication) step by step, but I can't get validate() method called when using @AuthGuard('local') or @AuthGuard(LocalAuthGuard) on login action.
If I don't use that guard decorator, all works as expected (but I need to use it to get my token added to request object).
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;
}
}
local.strategy.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;
}
}
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 {}
PS : I've already read all stack overflow related posts (for exemple : NestJS' Passport Local Strategy "validate" method never called) but they didn't help me.
Solution 1:[1]
I found that if we don't pass email or password, also the wrong value of both, the guard will response Unauthorized message. The problem is how to ensure that validation of the required field before run guard logic if it not defined, In other words, frontend not pass it to server. If we add @Body() data: loginDto in controller method, it won't validate the body params.
to solve it, I add some validation code in local.guard.ts file. Here is my code in my project:
import { HttpException, HttpStatus, Injectable, UnauthorizedException } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {
handleRequest(err, user, info, context, status) {
const request = context.switchToHttp().getRequest();
const { mobile, password } = request.body;
if (err || !user) {
if (!mobile) {
throw new HttpException({ message: '???????' }, HttpStatus.OK);
} else if (!password) {
throw new HttpException({ message: '??????' }, HttpStatus.OK);
} else {
throw err || new UnauthorizedException();
}
}
return user;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jenemy |
