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