typescriptauthenticationnestjspassport-localnestjs-passport

Nest.js authentication with passport-local result in Error: Unknown authentication strategy "local"


I am new to Nest.js and currently trying to figure out how to get my authentication to run. I use passport-local and followed the tutorial on the offical Nest.js website, but I keep getting the error Unknown authentication strategy "local". Here is my code as I dont have anything more to say (I left some services like user service out, as I think they do not have anything to do with the problem, but I can send them on request). This is my "first" real question (I asked some question when I was little some years ago). I hope this is not too much code, but I dont know how else to state my problem. I hope this is okay. Thanks for you help! :)

auth.module.ts:

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

@Module({ 
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy]
})
export class AuthModule {}

local-auth.guard.ts:

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

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

local.strategy.ts:

import { Injectable } from "@angular/core"
import { UnauthorizedException } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport"
import { Strategy } from "passport-local"
import { AuthService } from "./auth.service"
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
    constructor(private authService: AuthService) {
        super();
    }

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

app.module.ts:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

app.controller.ts

import { Controller, Get, Post, Request, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from '../auth/local-auth.guard';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @UseGuards(LocalAuthGuard)
  @Post('login')
  login(@Request() req): any {
    return req.user;
  }

  @Get('protected')
  getData() {
    return this.appService.getData();
  }
}

auth.service.ts

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {

    constructor (private userService: UsersService) {}

    async validateUser(username: string, password: string): Promise<any> {
        const user = await this.userService.existsUser(username);
        if (user && (user.password === password)) {
            const {password, username, ...rest} = user; 
            return rest;
        }
        return null;
    } 
}

user.service.ts

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

export type User = {
    id: number,
    name: string,
    username: string,
    password: string
}

@Injectable()
export class UsersService {
    private readonly users: User[] = [
        {
            id: 1,
            name: "testname",
            username: "cooluser",
            password: "admin"
        }
    ];

    async existsUser(username: string): Promise<User | undefined> {
        return this.users.find( (user) => {
            user.username === username;
        });
    }
}

users.module.ts

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
    providers: [UsersService],
    exports: [UsersService]
})
export class UsersModule {}

Solution

  • Oh! Your AppMoule needs to import your AuthModule so the passport strategy gets registered