NestJS身份验证策略-如何访问?

NestJS身份验证策略-如何访问?,nestjs,nestjs-passport,Nestjs,Nestjs Passport,所以,我很困惑。我正在慢慢地掌握NestJS,但是passport的工作方式让我感到困惑 我遵循规则,一切正常 我创建了一个JWT战略: @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor(private prisma: PrismaService) { super({ jwtFromRequest: ExtractJwt.f

所以,我很困惑。我正在慢慢地掌握NestJS,但是
passport
的工作方式让我感到困惑

我遵循规则,一切正常

我创建了一个JWT战略:

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
    constructor(private prisma: PrismaService) {
        super({
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            secretOrKey: 'topSecret51',
        });
    }

    async validate(payload: JwtPayload): Promise<User | null> {
        const { email } = payload;
        const user = await this.prisma.user.findOne({
            where: { email }
        });

        if (!user) {
            throw new UnauthorizedException('Athorisation not provided')
        }
        return user;
    }
}
然后一个有效的令牌被发出。我不明白的是
passport
如何访问
JwtStrategy
。passport如何知道我的文件夹结构中有一个文件包含
JwtStrategy

1.)它不是由
PassportModule
JWTModule
2.)它不会作为参数传递给任何方法


是否有一些幕后魔法可以检查所有提供程序,并确定其中是否有一个是提供给
PassportStrategy
的参数的子类?

NestJS的passport模块有很多魔法。我会尽我所能解释这一切是如何运作的,尽管有时甚至超出了我的理解范围

首先要注意的是,每个
PassportStrategy
都必须扩展抽象的mixin
PassportStrategy
。此mixin从常规passport包中获取
策略
(本例中为
passport jwt
)。此策略有一个默认名称(
jwt
),但您可以传递第二个参数来提供自己的名称

Nest做了一些非常酷的魔术,将
CustomStrategy
构造函数的
super()
调用中的值传递给passports正常注册。然后它接受
CustomStrategy#validate
并将其应用于passport的验证回调,这就是
validate
方法必须与passport预期的
verify
回调匹配的原因

现在我们已经使用passport进行了一些注册,但是为了正确调用这些,我们需要查看
AuthGuard
mixin。通常,我们可以将一个策略传递给mixin,该策略需要匹配passport策略的名称(如本例中的
jwt
),或者可以在
PassportModule
defaultStrategy
选项中进行设置。从这里开始,守卫会施展一点魔法,按名称调用策略(
jwt
google
local
,等等),并从http上下文中传递
请求
响应
,以及
下一步
。在调用结束时,
request.user
通过
passport.authenticate
返回的值进行设置

@Module({
  imports: [
    PassportModule.register({
      defaultStrategy: 'jwt',
    }),
    JwtModule.register({
      secret: 'topSecret51',
      signOptions: {
        expiresIn: 3600,
      },
    })
  ],
  providers: [UserService, PrismaService, JwtStrategy],
  controllers: [UserController],
  exports: [JwtStrategy, PassportModule],
})
export class UserModule {}