NestJS Unknown authentication strategy "local"

Viewed 783

I have this code in NestJs with the following files below, but now it says "Unknown authentication strategy "local"", I've already looked for solutions and they all point to an import error, but I have the localstrategy imported into auth.module and app.module (I've already tested taking it out of app.module but it doesn't change anything.)

app.module.ts

    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { ThrottlerModule } from '@nestjs/throttler';
    import { MongooseModule } from '@nestjs/mongoose';
    import { AuthModule } from './auth/auth.module';
    import { UsersModule } from './users/users.module';
    import { LocalStrategy } from './auth/local.strategy';

    @Module({
      imports: [
        MongooseModule.forRoot(
          'mongodb+srv://user:password@db.db.mongodb.net/db?retryWrites=true&w=majority',
        ),
        ThrottlerModule.forRoot({
          ttl: 60,
          limit: 10,
        }),
        AuthModule,
        UsersModule,
      ],
      controllers: [AppController],
      providers: [AppService, LocalStrategy],
    })
    export class AppModule {}

auth.module.ts

      import { Module } from '@nestjs/common';
  import { AuthService } from './auth.service';
  import { UsersModule } from '../users/users.module';
  import { PassportModule } from '@nestjs/passport';
  import { LocalStrategy } from './local.strategy';
  import { JwtModule } from '@nestjs/jwt';
  import { JwtStrategy } from './jwt.strategy';
  import 'dotenv/config';

  @Module({
    imports: [
      UsersModule,
      PassportModule,
      JwtModule.register({
        secret: process.env.JWTSECRET,
        signOptions: { expiresIn: '60s' },
      }),
    ],
    providers: [AuthService, LocalStrategy, JwtStrategy],
    exports: [AuthService],
  })
  export class AuthModule {}

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({ usernameField: 'email' });
    }

    async validate(email: string, password: string): Promise<any> {
      const user = await this.authService.validateUser(email, password);
      if (!user) {
        throw new UnauthorizedException();
      }
      return user;
    }
  }

app.controller.ts

    import {
  Controller,
  Request,
  Post,
  UseGuards,
  Res,
  Get,
  Body,
} from '@nestjs/common';
import { AuthService } from './auth/auth.service';
import { MakeAuthDto } from './auth/dto/make-auth.dto';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { Roles } from './utils/decorators/roles.decorator';
import { Role } from './utils/enums/role.enum';
import { RolesGuard } from './utils/guards/roles.guard';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(
    @Body() _: MakeAuthDto,
    @Request() req,
    @Res({ passthrough: true }) res,
  ) {
    console.log(req.user);
    const access_token = await this.authService.login(req.user);
    res.cookie('jwt', access_token);
    return req.user;
  }

  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(Role.Admin)
  @Get('tests')
  getProfile(@Request() req) {
    return req.user;
  }
}

local-auth.guard.ts

        import { Injectable } from '@nestjs/common';
    import { AuthGuard } from '@nestjs/passport';

    @Injectable()
    export class LocalAuthGuard extends AuthGuard('local') {}

auth.service.ts

    import { Injectable } from '@nestjs/common';
import { UsersService } from 'src/users/users.service';
import { JwtService } from '@nestjs/jwt';
import { UserDocument } from 'src/users/entities/user.entity';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService,
  ) {}

  async validateUser(email: string, pass: string): Promise<UserDocument | any> {
    const user = await this.usersService.findOne(email);
    if (user && (await user.compareHash(pass))) {
      const { password, ...result } = user.toObject();
      await this.usersService.updateLastLogin(user._id);
      return result;
    }
    return null;
  }

  async login(user: UserDocument): Promise<string> {
    const payload = { email: user.email, sub: user._id, roles: user.roles };
    return this.jwtService.sign(payload);
  }
}

jwt-auth.guard.ts

        import { Injectable } from '@nestjs/common';
    import { AuthGuard } from '@nestjs/passport';

    @Injectable()
    export class JwtAuthGuard extends AuthGuard('jwt') {}

jwt.strategy.ts

    import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import 'dotenv/config';

const cookieExtractor = function (req) {
  let token = null;
  if (req && req.cookies) {
    token = req.cookies['jwt'];
  }
  return token;
};

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromExtractors([cookieExtractor]),
      ignoreExpiration: false,
      secretOrKey: process.env.JWTSECRET,
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, email: payload.email, roles: payload.roles };
  }
}

enter image description here

No similar question on stackoverflow solved my problem, does anyone know what it can be?

0 Answers
Related