NestJS - AuthGuard 如何了解 Passport 策略?

Sam*_*e11 7 node.js passport.js nestjs

当涉及到身份验证/授权过程时,我很难弄清楚 NestJS 和 PassportJS 的组合,而且我是一种在开发时不喜欢魔法的开发人员。

问题

基本上,我的目标是了解 AuthGuard 如何知道项目中正在实施的 Passport 策略,它可以是本地策略,也可以是任何其他策略,例如 JWT 策略。我有两个模块AuthModuleUserModule,这就是AuthService的样子:

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

    async validateUser(username: string, password: string): Promise<any> {
        const user = await this.usersService.findOne(username);

        if (user && user.password === password) {
            const {password, ...result} = user
            return result
        }
        return null
    }
}
Run Code Online (Sandbox Code Playgroud)

用户服务

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

export type User = any;

@Injectable()
export class UsersService {

    private readonly users = [
        {
            userId: 1,
            username: 'John Marston',
            password: 'rdr1',
        },
        {
            userId: 2,
            username: 'Arthur Morgan',
            password: 'rdr2',
        },
    ]

    async findOne(username: string): Promise<User | undefined> {
        return this.users.find(user => user.username === username)
    }
}
Run Code Online (Sandbox Code Playgroud)

护照

安装 Passport 和 NestJS 的软件包后,我导入了PassportModule并实现了LocalStrategy,并将该策略作为提供程序导入到 AuthModule

本地策略

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)
@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy]
})
export class AuthModule {}
Run Code Online (Sandbox Code Playgroud)

登录路线

import { Controller, Post, Request, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  
  @UseGuards(AuthGuard('local'))
  @Post('login')
  async login(@Request() req) {
    return req.user;
  }
}
Run Code Online (Sandbox Code Playgroud)

直到这一部分我都明白了。我也明白我们如何获取 req.user 对象等,但我不明白 AuthGuard 如何知道我们实施了 Passport 本地策略。它是否会查看文件(抱歉,如果这么说很愚蠢)并找到我们导入 PassportModule 的位置以及我们实现LocalStrategy 的位置,因为该类扩展了 PassportStrategy 类,但同样重要的是,是从 Passport-local 导入的。

我确实知道AuthGuard是一种特殊类型的 Guard,但我不确定我是否理解正确。

Jay*_*iel 5

我有一篇关于此的相当好的文章,但也将其放在 StackOverflow 上:

Strategy包中的每个属性passport-*都有一个name属性,即策略的名称。因为passport-localnamelocal。因为passport-jwt,那个名字是'jwt'。这并不总是一一对应,但每个包裹都应记录其护照名称。passport.use()这是传递给和的名称passport.authenticate()passport.use通过类中的一些巧妙的代码调用PassportStrategy@nestjs/passport将策略注册到 Passport 中,并在使用通过 Passport 模块的选项或通过 mixin 的参数设置的全局默认值的passport.authenticate内部进行调用,如代码示例中所示。AuthGuard()local