16

I am trying to implement a JWT strategy for authentication in my nest application.
I am getting the following error tho

Unknown authentication strategy "jwt"

This is my code:
jwt.strategy.ts

import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { Strategy } from "passport-local";
import { ExtractJwt } from "passport-jwt";
import { jwtConstants } from "./constants";

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    })
  }

  async validate(payload: any) {
    console.log(payload);
    return { userId: payload.sub, username: payload.username };
  }
}

My Authentication Module:
authentication.module.ts

import { Module } from '@nestjs/common';
import { AuthenticationService } from './authentication.service';
import { UsersModule } from 'src/users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';
import { JwtStrategy } from './jwt.strategy';

@Module({
  providers: [
    AuthenticationService,
    LocalStrategy,
    JwtStrategy
  ],
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: "1d" },
    })
  ],
  exports: [AuthenticationService]
})
export class AuthenticationModule {}

And I am trying to use it in the following controller:
users.controller.ts

import { Controller, Post, Body, Put, Param, Get, UseGuards } from '@nestjs/common';
import { User } from './user.entity';
import { UsersService } from './users.service';
import { JwtAuthGuard } from 'src/authentication/jwt-auth.guard';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @UseGuards(JwtAuthGuard)
  @Get()
  async getAll(){
    return this.usersService.findAll();
  }
}

The Users Module looks like this:
users.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
  exports: [UsersService]
})
export class UsersModule {}

JwtAuthGuardis just a class that extends from AuthGuard('jwt') I have follow the nestjs authentication guide from the official docs, but cant get it running in my UsersModule

Arnold Schrijver
  • 3,588
  • 3
  • 36
  • 65
Jan Krüger
  • 786
  • 1
  • 5
  • 16
  • Have you imported `AuthenticationModule` inside your UserModule? Be sure to export `PassportModule` and `JwtModule` as well inside your AuthenticationModule's export – Mohd.Zafranudin Feb 27 '20 at 09:42

4 Answers4

36

The issue was that autoimport imported Strategy from the wrong package

import {Strategy} from "@nest/passport-local";

instead of

import { Strategy } from "passport-jwt";
Jan Krüger
  • 786
  • 1
  • 5
  • 16
30

For me, I was missing importing JwtStrategy into auth.module.ts providers

@Module({
  controllers: [AuthController],
  imports: [
    PassportModule,
    JwtModule.register({
      secret: 'nomnom',
      signOptions: { expiresIn: '1d' },
    }),
  ],
  exports: [AuthService],
  providers: [AuthService, AccountService, LocalStrategy, JwtStrategy], // Here, make sure you have imported LocalStrategy and JwtStrategy.
})
export class AuthModule {}
Manjunath Reddy
  • 1,039
  • 2
  • 13
  • 22
  • Thanks brother! I was learning nestJs and was confused at this point. Seems like a silly mistake :) – emilpmp Feb 23 '23 at 14:05
7

Import your Authentication Module inside your User Module, then your user service will detect it.

user.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
// import authentication module here

@Module({
  imports: [
    AuthenticationModule, // add this here
    TypeOrmModule.forFeature([User])
  ],
  providers: [UsersService],
  controllers: [UsersController],
  exports: [UsersService]
})
export class UsersModule {}

authentication.module.ts

import { Module } from '@nestjs/common';
import { AuthenticationService } from './authentication.service';
import { UsersModule } from 'src/users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';
import { JwtStrategy } from './jwt.strategy';

@Module({
  providers: [
    AuthenticationService,
    LocalStrategy,
    JwtStrategy
  ],
  imports: [
    // UsersModule, # exclude this, your authentication module is not using it
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: "1d" },
    })
  ],
  exports: [
    JwtModule,
    PassportModule,
    AuthenticationService,

  ]
})
export class AuthenticationModule {}

Also I notice you imported UserModule inside AuthenticationModule, but from your code you are not using it anywhere. So kindly remove it to avoid circular dependency.

Mohd.Zafranudin
  • 364
  • 4
  • 12
  • I am Using the UserService that is beeing provided by the UserModule, so I need it in my AuthModule. I didnt need to import the AuthModule in my UserModule tho. So there is no circular dependency. It was an autoimport issue. – Jan Krüger Feb 28 '20 at 10:44
  • Your answer really helped me and yes, the last step of removing UserModule from AuthModule's dependencies is not needed as Nest will not be able to use userService i authservice if that is done – myestery Mar 16 '21 at 16:15
  • Make sure you have Strategies imported into your providers' ex: ```providers: [ AuthenticationService, LocalStrategy, JwtStrategy ],``` – Manjunath Reddy Jul 04 '21 at 16:11
6

after several times got 401 error because of this wrong autoimport

import { Strategy } from "passport-local";

change this line to

import { Strategy } from "passport-jwt";
Sugi
  • 61
  • 2
  • 1