#Error: Unknown authentication strategy "local"

1 messages · Page 1 of 1 (latest)

open magnet
#

Hi Everybody,

I have a problem with Passport Strategy, either jwt or local strategy I have the same error: Error: Unknown authentication strategy "local/jwt"

I just followed the nest documentation (https://docs.nestjs.com/recipes/passport) to implement it:

Here is my local.strategy.ts file:
`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;
}
}`

Here is my auth.module.ts:
`import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UserModule } from 'src/user/user.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

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

#

Here is my app.controller.ts:
`import { Controller, Get, UseGuards, Request, Post } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { AppService } from './app.service';

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

@UseGuards(AuthGuard('local'))
@Post('auth/login')
async login(@Request() req) {
return req.user;
}
}`

and here is my package.json:
...
"dependencies": {
"@hapi/joi": "^17.1.1",
"@nestjs/common": "^10.0.4",
"@nestjs/config": "^3.0.0",
"@nestjs/core": "^10.0.4",
"@nestjs/jwt": "^10.1.0",
"@nestjs/mapped-types": "^2.0.2",
"@nestjs/passport": "^10.0.0",
"@nestjs/platform-express": "^10.0.4",
"@nestjs/swagger": "^7.0.12",
"@nestjs/throttler": "^4.1.0",
"@nestjs/typeorm": "^10.0.0",
"@types/bcrypt": "^5.0.0",
"bcrypt": "^5.1.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"crypto-random-string": "^3.3.1",
"mysql2": "^3.3.5",
"passport": "^0.6.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
"typeorm": "^0.3.16"
},
....
`
If you have any ideas it would be very helpfull
Thanks in advance

viral sparrow
#

Can you show the AuthService?

open magnet
#

import { Injectable } from '@nestjs/common';
import { UserService } from 'src/user/user.service';
import * as bcrypt from 'bcrypt';

@Injectable()
export class AuthService {
constructor(private usersService: UserService) {}

async validateUser(email: string, pass: string): Promise<any> {
const user = await this.usersService.findOneByEmail(email);
const challenge = await bcrypt.compare(
pass,
user.password
);
if (user) {
if (challenge) {
const { password, ...result } = user;
return result;
}
return null;
}
return null;
}
}

steady galeBOT
#

Please format your question with Markdown formatting.
It leads to better readability and an easier time to spot problems.
For code blocks, you can wrap your block with three back ticks before and after the block, and after the first three back ticks you can add a language (like ts) to add syntax highlighting.
e.g.

```ts
@Injectable()
export class MySuperAwesomeService {
constructor(@Inject('InjectionToken') private readonly dep: SomeDependency) {}

getRandomNumber(): number {
return Math.round(Math.random() * 1000);
}
}
```

Becomes

@Injectable()
export class MySuperAwesomeService {
  constructor(@Inject('InjectionToken') private readonly dep: SomeDependency) {}

  getRandomNumber(): number {
    return Math.round(Math.random() * 1000);
  }
}
viral sparrow
#

Okay, can you show UserService?

open magnet
#

import { CreateUserDto } from './dto/create-user.dto';
import { Inject, Injectable, Logger, NotFoundException, Scope } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';

@Injectable({ scope: Scope.REQUEST })
export class UserService {
/**
*

constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) { }

async create(createUserDto: CreateUserDto) {
const user = this.userRepository.create(createUserDto);
await this.userRepository.save(user);
this.logger.log('User Created : ' + user);
return user;
}

async findAll() {
const user = await this.userRepository.find();
console.log(user);

return user;

}

async findOne(uuid: string) {
let user = await this.userRepository.findOne({
where: {
uuid: uuid
}
});
if (!user) {
throw new NotFoundException(uuid, "User with uuid " + uuid + " not found.");
}
return user;
}

async findOneByEmail(email: string) {
const user = await this.userRepository.findOne({ where: { email: email } });
if (user) {
return user;
}
throw new NotFoundException(email, "User with email " + email + " not found.");
}

}

viral sparrow
#

Code blocks. Please.

open magnet
#

`import { CreateUserDto } from './dto/create-user.dto';
import { Inject, Injectable, Logger, NotFoundException, Scope } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';

@Injectable({ scope: Scope.REQUEST })
export class UserService {
/**
*

@private Logger*/
private readonly logger = new Logger(UserService.name);

constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) { }

async create(createUserDto: CreateUserDto) {
const user = this.userRepository.create(createUserDto);
await this.userRepository.save(user);
this.logger.log('User Created : ' + user);
return user;
}

async findAll() {
const user = await this.userRepository.find();
console.log(user);

return user;

}

async findOne(uuid: string) {
let user = await this.userRepository.findOne({
where: {
uuid: uuid
}
});
if (!user) {
throw new NotFoundException(uuid, "User with uuid " + uuid + " not found.");
}
return user;
}

async findOneByEmail(email: string) {
const user = await this.userRepository.findOne({ where: { email: email } });
if (user) {
return user;
}
throw new NotFoundException(email, "User with email " + email + " not found.");
}
}`

viral sparrow
#

Three back ticks, like the message bot's message shows

open magnet
#

you do not see the code ?

viral sparrow
#

I do. It looks ugly. This is what I'm meaning it should look like witha proper code block:

import { CreateUserDto } from './dto/create-user.dto';
import { Inject, Injectable, Logger, NotFoundException, Scope } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';


@Injectable({ scope: Scope.REQUEST })
export class UserService {
  /**
 *
 
@private Logger*/
private readonly logger = new Logger(UserService.name);

  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
  ) { }

  async create(createUserDto: CreateUserDto) {
    const user = this.userRepository.create(createUserDto);
    await this.userRepository.save(user);
    this.logger.log('User Created : ' + user);
    return user;
  }

  async findAll() {
    const user = await this.userRepository.find();
    console.log(user);

    return user;
  }

  async findOne(uuid: string) {
    let user = await this.userRepository.findOne({
      where: {
        uuid: uuid
      }
    });
    if (!user) {
      throw new NotFoundException(uuid, "User with uuid " + uuid + " not found.");
    }
    return user;
  }


  async findOneByEmail(email: string) {
    const user = await this.userRepository.findOne({ where: { email: email } });
    if (user) {
      return user;
    }
    throw new NotFoundException(email, "User with email " + email + " not found.");
  }
}

Syntax highlighting, and easy to read

open magnet
dusty valve
#

I have the same problem. What is the solution ?

viral sparrow
dusty valve
#

I don´t got it bro

viral sparrow
#

That's the guard, not the strategy

dusty valve
#
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { AuthRepository } from "@masterTools/domain/repositories/auth/auth.repository";
import { UserEntity } from "@masterTools/domain/user/user.entity";


@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly repository: AuthRepository) {
    super({
      usernameField: 'email',
    });
  }

  async validate(email: string, password: string): Promise<UserEntity> {
    return this.repository.authenticateUser(email, password);
  }
}
steady galeBOT
#

Please format your question with Markdown formatting.
It leads to better readability and an easier time to spot problems.
For code blocks, you can wrap your block with three back ticks before and after the block, and after the first three back ticks you can add a language (like ts) to add syntax highlighting.
e.g.

```ts
@Injectable()
export class MySuperAwesomeService {
constructor(@Inject('InjectionToken') private readonly dep: SomeDependency) {}

getRandomNumber(): number {
return Math.round(Math.random() * 1000);
}
}
```

Becomes

@Injectable()
export class MySuperAwesomeService {
  constructor(@Inject('InjectionToken') private readonly dep: SomeDependency) {}

  getRandomNumber(): number {
    return Math.round(Math.random() * 1000);
  }
}
viral sparrow
#

Your AuthRepository, is it REQUEST scoped? Or does it inject anything that is?

dusty valve
#
import { UserEntity } from "@masterTools/domain/user/user.entity";

export abstract class AuthRepository{
  public abstract authenticateUser(email: string, plainTextPassword: string): Promise<UserEntity>;

  public abstract getAccessToken(payload: TokenPayload): Promise<string>;
}

#
import { Injectable } from "@nestjs/common";
import { AuthDataSource } from "@masterTools/data/data_source/auth/auth.datasource";
import { UserEntity } from "@masterTools/domain/user/user.entity";
import { AuthRepository } from "@masterTools/domain/repositories/auth/auth.repository";

@Injectable()
export class AuthRepositoryImpl implements AuthRepository {
  constructor(private readonly dataSource: AuthDataSource) {}

  public authenticateUser(
    email: string,
    plainTextPassword: string): Promise<UserEntity> {
    return this.dataSource.authenticateUser(email, plainTextPassword);
  }

  public getAccessToken(payload: TokenPayload): Promise<string> {
    return this.dataSource.getAccessToken(payload);
  }
}
#

This is my repository inside the data structure of clean arch.

viral sparrow
#

What about the actual provider implementation? Where you define provide: AuthRepository.

Okay AuthRepositoryImpl, do you have a request scoped AuthDataSource?

dusty valve
#

Both is @Injectable()

viral sparrow
#

But do they @Inject(REQUEST)?

dusty valve
#
@Injectable()
export class AuthDataSourceImpl extends BaseDataSourceImpl<UserEntity> implements AuthDataSource {
  constructor(
    protected readonly moduleRef: ModuleRef,
    @Inject(REQUEST) protected request: Record<string, unknown>,
    private readonly userDataSource: UserDataSource,
    private readonly jwtService: JwtService,
  ) {
    super(moduleRef, request);
  }````
#

Have bro

#

I see now

viral sparrow
#

Yep. That makes it REQUEST scoped

#

The link above shows how towork with that

dusty valve
#

I removed protected readonly moduleRef: ModuleRef,
@Inject(REQUEST) protected request: Record<string, unknown>, but not work.

#

Oh but userDataSource have the same injection