前文
我们之前已经分析到了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(校验)创造一个父类
通过我们自己写的类继承于父类
在类初始化的时候实现自动注册
结语
撒花~