I am trying to use the authguard here in nest js but i am getting this unauthorized error constantly , let me share all the codes here
//auth service
import { Injectable, UseFilters } from '@nestjs/common';
import { CreateAuthDto } from './dto/create-auth.dto';
import { UpdateAuthDto } from './dto/update-auth.dto';
import { InjectModel } from '@nestjs/mongoose';
import { AuthDocument ,Auth } from './Schema/userAuth';
import { Model } from 'mongoose';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(@InjectModel(Auth.name) private AuthModel:Model<AuthDocument> ,private JwtService :JwtService){
};
create(createAuthDto: CreateAuthDto):Promise<Auth> {
console.log(createAuthDto);
const user= new this.AuthModel;
user.Name= createAuthDto.Name;
user.Username= createAuthDto.Username;
user.Email = createAuthDto.Email;
user.Password = createAuthDto.Password;
return user.save();
}
async login(Username: string, Password: string): Promise<any> {
try {
const user = await this.AuthModel.findOne({ Username:Username }).exec();
if(!user){
return 'user not found' ;
}
if(user.Password == Password){
const payload = { Username ,Password} ;
const accessToken = this.JwtService.sign(payload)
console.log(payload);
console.log(accessToken);
return {accessToken};
}
} catch (error) {
console.error('Error finding user:', error);
return 'Error finding user';
}
}
findAll() {
return `This action returns all auth`;
}
findOne(Email:string) :Promise<Auth> {
const user = this.AuthModel.findOne({Email:Email})
return user;
}
update(id: number, updateAuthDto: UpdateAuthDto) {
return `This action updates a #${id} auth`;
}
remove(id: number) {
return `This action removes a #${id} auth`;
}
}
//auth module
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { MongooseModule } from '@nestjs/mongoose';
import { userSchema ,Auth} from './Schema/userAuth';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './strategies/local.strategy';
import { LocalGuard } from './guards/local.guard';
@Module({
imports:[MongooseModule.forFeature([{name:Auth.name,schema:userSchema}]) ,
JwtModule.register({
secret:"H@rsh123",
signOptions:{
expiresIn:"1h"
}
}),PassportModule],
controllers: [AuthController ],
providers: [AuthService ,LocalStrategy ,LocalGuard],
})
export class AuthModule {}
//auth control
import { Controller, Get, Post, Body, Patch, Param, Delete, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { CreateAuthDto } from './dto/create-auth.dto';
import { UpdateAuthDto } from './dto/update-auth.dto';
import { AuthGuard } from '@nestjs/passport';
import { LocalGuard } from './guards/local.guard';
import { LocalStrategy } from './strategies/local.strategy';
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}
@Post('signup')
create(@Body() createAuthDto: CreateAuthDto) {
return this.authService.create(createAuthDto);
}
@Post('login')
@UseGuards(LocalGuard)
async login(@Body() requestBody:{Username:string ,Password :string}){
const {Username , Password} = requestBody;
const user= await this.authService.login(Username , Password);
if(!user){
return 'invalid user';
}
return user;
}
@Get()
findAll() {
return this.authService.findAll();
}
@Get(':Username')
findOne(@Param('Username') Username: string) {
return this.authService.findOne(Username);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateAuthDto: UpdateAuthDto) {
return this.authService.update(+id, updateAuthDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.authService.remove(+id);
}
}
//local-strategy
// local.strategy.ts
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from '../auth.service';
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super();
}
async validate(payLoad :any): Promise<any> {
const {username,password} = payLoad;
console.log('user', username, password);
const user = await this.authService.login(username, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
//localguard
import { ExecutionContext, Injectable } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
import { Observable } from "rxjs";
@Injectable()
export class LocalGuard extends AuthGuard('local'){
canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
console.log('hello');
return super.canActivate(context);
}
}
everything works correctly if I remove thw @UseGuards() but when i use it it always gives unauthorized error with 401 code , the validate function isnt even being called because the console.log statement doesnt print on the output, please help
Passport expects you to send
usernameandpasswordas fields of the request body. If you want to use something else, likeUsername, and yes, capitalization matters, then you need to tell passport about this change. You can do so by passing options to thesupermethod of theLocalStrategyconstructor, e.g.Also take note that the
validatemethod has two parameters, theusernamefield value and thepasswordfield value.