Continous Unuathorised message response on using authguard in nest .js

24 Views Asked by At

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

1

There are 1 best solutions below

1
Jay McDoniel On

Passport expects you to send username and password as fields of the request body. If you want to use something else, like Username, and yes, capitalization matters, then you need to tell passport about this change. You can do so by passing options to the super method of the LocalStrategy constructor, e.g.

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({
      usernameField: 'Username',
      passwordField: 'Password',
    });
  }

  async validate(username :string, password: string): Promise<any> {
    console.log('user', username, password);
    const user = await this.authService.login(username, password);

    if (!user) {
      throw new UnauthorizedException();
    }

    return user;
  }
}

Also take note that the validate method has two parameters, the username field value and the password field value.