Как AuthGuard находит реализацию своей Стратегии в Nest.js?

Изучаю реализацию стратегии Passport local в официальной документации (репозиторий).

// 19-auth-jwt/src/auth/auth.module.ts 

/*...*/
import { LocalStrategy } from './strategies/local.strategy';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
// 19-auth-jwt/src/auth/guards/local-auth.guard.ts

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

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
// 19-auth-jwt/src/auth/strategies/local.strategy.ts

import { Injectable, 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 readonly 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;
  }
}

Обнаруживаю, что LocalAuthGuard и его LocalStrategy вообще никак не связаны явным образом:

// 19-auth-jwt/src/app.module.ts 

/*...*/

@Module({
  imports: [AuthModule, UsersModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
// 19-auth-jwt/src/app.controller.ts 

/*...*/
import { LocalAuthGuard } from './auth/guards/local-auth.guard';

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

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }

  /*...*/
}

Итак, каким образом этот LocalAuthGuard extends AuthGuard('local') находит реализацию своей Стратегии?


Ответы (1 шт):

Автор решения: Артём Ионаш

Этими AuthGuard() управляет PassportModule из пакета @nestjs/passport:

// 19-auth-jwt/src/auth/auth.module.ts

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

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

Его можно настраивать, например таким образом:

    PassportModule.register({
      defaultStrategy: 'jwt',
      property: 'user',
      session: false,
    })

Но я всё ещё не понимаю, каким образом это документировано, и документировано ли вообще. Похоже, что всё-таки никак это и не задокументировано по-человечески.

→ Ссылка