李恒道 发表于 2022-12-4 01:52:05

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

# 前文
我们之前已经分析到了passport,这次我们继续往passport-local分析
# 正文
我们之前在local.strategy.ts写了local的代码
```js
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
```js
function PassportStrategy(Strategy, name) {
    class MixinStrategy extends Strategy {
         constructor(...args) {
             xxxxxxx
         }
      
         getPassportInstance() {
            return passport;
      }
    }
}
```
可以看到这个函数调用返回了一个类
这个类继承我们传入的类
同时有一个getPassportInstance以及一个constructor构造函数
我们只需要看构造函数即可,getPassportInstance属于一个逃生仓函数
```js
      constructor(...args) {
            const callback = (...params) => __awaiter(this, void 0, void 0, function* () {
                const done = params;
                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类型声明
```js
declare class Strategy extends PassportStrategy {
    constructor(
      options: IStrategyOptionsWithRequest,
      verify: VerifyFunctionWithRequest
    );
    constructor(options: IStrategyOptions, verify: VerifyFunction);
    constructor(verify: VerifyFunction);

    name: string;
}
```
可以发现第二个参数是一个验证函数,可以知道callback会被继承为我们的验证函数
我们先不管,继续往下看
```js
            const passportInstance = this.getPassportInstance();
            if (name) {
                passportInstance.use(name, this);
            }
            else {
                passportInstance.use(this);
            }
```
这里得到了passport的对象,然后将策略注册到了passport上
我们没有填写name,所以调用的是passportInstance.use(this);
而use内部调用的是策略的name
我们去翻一下passport-local的源码,找到了初始化会进行
```js
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(校验)创造一个父类
通过我们自己写的类继承于父类
在类初始化的时候实现自动注册
# 结语
撒花~
页: [1]
查看完整版本: nestjs passport及@nestjs/passport源码级分析(四)