上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

nestjs passport及@nestjs/passport源码级分析(四)

[复制链接]
  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    637

    主题

    5191

    回帖

    6075

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6075

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-12-4 01:52:05 | 显示全部楼层 | 阅读模式

    前文

    我们之前已经分析到了passport,这次我们继续往passport-local分析

    正文

    我们之前在local.strategy.ts写了local的代码

    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();
      }
      async validate(username: string, password: string): Promise<any> {
        return await this.authService.validate(username, password);
      }
    }

    我们继续分析
    从PassportStrategy往里读吧,我们往里传入了passport-local的Strategy

    function PassportStrategy(Strategy, name) {
        class MixinStrategy extends Strategy {
             constructor(...args) {
                 xxxxxxx
             }
    
             getPassportInstance() {
                return passport;
            }
        }
    }

    可以看到这个函数调用返回了一个类
    这个类继承我们传入的类
    同时有一个getPassportInstance以及一个constructor构造函数
    我们只需要看构造函数即可,getPassportInstance属于一个逃生仓函数

            constructor(...args) {
                const callback = (...params) => __awaiter(this, void 0, void 0, function* () {
                    const done = params[params.length - 1];
                    try {
                        const validateResult = yield this.validate(...params);
                        if (Array.isArray(validateResult)) {
                            done(null, ...validateResult);
                        }
                        else {
                            done(null, validateResult);
                        }
                    }
                    catch (err) {
                        done(err, null);
                    }
                });
                super(...args, callback);
                const passportInstance = this.getPassportInstance();
                if (name) {
                    passportInstance.use(name, this);
                }
                else {
                    passportInstance.use(this);
                }
            }

    super(...args, callback);
    这里callback传入给了父类
    我们观察一下passport-local的ts类型声明

    declare class Strategy extends PassportStrategy {
        constructor(
            options: IStrategyOptionsWithRequest,
            verify: VerifyFunctionWithRequest
        );
        constructor(options: IStrategyOptions, verify: VerifyFunction);
        constructor(verify: VerifyFunction);
    
        name: string;
    }

    可以发现第二个参数是一个验证函数,可以知道callback会被继承为我们的验证函数
    我们先不管,继续往下看

                const passportInstance = this.getPassportInstance();
                if (name) {
                    passportInstance.use(name, this);
                }
                else {
                    passportInstance.use(this);
                }

    这里得到了passport的对象,然后将策略注册到了passport上
    我们没有填写name,所以调用的是passportInstance.use(this);
    而use内部调用的是策略的name
    我们去翻一下passport-local的源码,找到了初始化会进行

    function Strategy(options, verify) {
      this._usernameField = options.usernameField || 'username';
      this._passwordField = options.passwordField || 'password';
      this._verify = verify;
      this.name = 'local';
      this._passReqToCallback = options.passReqToCallback;
    }

    所以刚好设置了local,并且验证函数会赋值到_verify上
    那初始化我们已经基本了解怎么注册的了

    总结

    在local类的初始化过程中会调用@nestjs/passport(校验)创造一个父类
    通过我们自己写的类继承于父类
    在类初始化的时候实现自动注册

    结语

    撒花~

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表