PassportJS、NestJS:AuthGuard 的 canActivate 方法('jwt')
PassportJS, NestJS: canActivate method of AuthGuard('jwt')
有人知道我在哪里可以看到 AuthGuard('jwt') 中 canActivate 方法的完整代码吗?我意识到 canActivate 方法通过使用 console.log() 调用 JwtStrategy validate 方法,如下所示:
// jwt.strategy.ts
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
private readonly configService: ConfigService,
private readonly usersService: UsersService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: true,
secretOrKey: configService.get<string>('JWT_SECRET'),
});
}
async validate(payload: any) {
try {
const user = await this.usersService.getUserById(payload.id);
// console.log is here
console.log(user);
return user;
} catch (e) {
console.log(e);
return null;
}
}
}
如果我使用原来的 canActivate 方法,会调用 console.log。我认为 JwtStrategy 是一个中间件,所以只要有请求就会调用 validate 方法。但是,当我尝试覆盖 canActivate 方法以添加授权时,未调用 JwtStrategy 验证方法中的 console.log:
// jwt-auth.guard.ts
import { ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
getRequest(context: ExecutionContext) {
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req;
}
canActivate(context: ExecutionContext): boolean {
try {
// Override: handle authorization
// return true or false
// Should JwtStrategy.validate(something) be called here?
} catch (e) {
console.log(e);
return false;
}
}
}
然后我试图找到AuthGuard('jwt')的原始代码以了解其逻辑,但我找不到。任何帮助将不胜感激,谢谢!
好的,所以这将是一个非常有趣的深入研究。系好安全带。
Middleware
as express methods do still exist in NestJS; that said, this is not your normal middleware in the sense of Express middleware. As you'v mentioned AuthGuard()#canActivate()
ends up calling the appropriate PassportStrategy
. These strategies get registered here 特别是在调用 passport.use()
的第 40-41 行。这注册了护照策略 class 的 validate
方法用于 passport.verify()
。大多数底层逻辑都非常抽象,阅读时可能会丢失上下文,因此请花点时间理解 classes、mixins(return class 的函数)的概念es)和继承。
Line 51 of AuthGuard is where the passportFn
originally gets created, and in this passportFn
passport.authenticate 被调用(在它的内部调用 passport.verify
)(通读 Passport 的代码更加令人困惑,所以我会在你需要的时候让你 运行) .
如果您想向 canActivate()
方法添加一些额外的逻辑,您可以最终调用 super.canActivate(context)
来调用最终调用 passport.authenticate()
的原始 canActivate()
方法因此 <Strategy>#validate
。这可能看起来像
@Injectable()
export class CustomAuthGuard extends AuthGuard('jwt') {
async canActivate(context: ExecutionContext): Promise<boolean> {
// custom logic can go here
const parentCanActivate = (await super.canActivate(context)) as boolean; // this is necessary due to possibly returning `boolean | Promise<boolean> | Observable<boolean>
// custom logic goes here too
return parentCanActivate && customCondition;
}
}
有人知道我在哪里可以看到 AuthGuard('jwt') 中 canActivate 方法的完整代码吗?我意识到 canActivate 方法通过使用 console.log() 调用 JwtStrategy validate 方法,如下所示:
// jwt.strategy.ts
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
private readonly configService: ConfigService,
private readonly usersService: UsersService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: true,
secretOrKey: configService.get<string>('JWT_SECRET'),
});
}
async validate(payload: any) {
try {
const user = await this.usersService.getUserById(payload.id);
// console.log is here
console.log(user);
return user;
} catch (e) {
console.log(e);
return null;
}
}
}
如果我使用原来的 canActivate 方法,会调用 console.log。我认为 JwtStrategy 是一个中间件,所以只要有请求就会调用 validate 方法。但是,当我尝试覆盖 canActivate 方法以添加授权时,未调用 JwtStrategy 验证方法中的 console.log:
// jwt-auth.guard.ts
import { ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
getRequest(context: ExecutionContext) {
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req;
}
canActivate(context: ExecutionContext): boolean {
try {
// Override: handle authorization
// return true or false
// Should JwtStrategy.validate(something) be called here?
} catch (e) {
console.log(e);
return false;
}
}
}
然后我试图找到AuthGuard('jwt')的原始代码以了解其逻辑,但我找不到。任何帮助将不胜感激,谢谢!
好的,所以这将是一个非常有趣的深入研究。系好安全带。
Middleware
as express methods do still exist in NestJS; that said, this is not your normal middleware in the sense of Express middleware. As you'v mentioned AuthGuard()#canActivate()
ends up calling the appropriate PassportStrategy
. These strategies get registered here 特别是在调用 passport.use()
的第 40-41 行。这注册了护照策略 class 的 validate
方法用于 passport.verify()
。大多数底层逻辑都非常抽象,阅读时可能会丢失上下文,因此请花点时间理解 classes、mixins(return class 的函数)的概念es)和继承。
Line 51 of AuthGuard is where the passportFn
originally gets created, and in this passportFn
passport.authenticate 被调用(在它的内部调用 passport.verify
)(通读 Passport 的代码更加令人困惑,所以我会在你需要的时候让你 运行) .
如果您想向 canActivate()
方法添加一些额外的逻辑,您可以最终调用 super.canActivate(context)
来调用最终调用 passport.authenticate()
的原始 canActivate()
方法因此 <Strategy>#validate
。这可能看起来像
@Injectable()
export class CustomAuthGuard extends AuthGuard('jwt') {
async canActivate(context: ExecutionContext): Promise<boolean> {
// custom logic can go here
const parentCanActivate = (await super.canActivate(context)) as boolean; // this is necessary due to possibly returning `boolean | Promise<boolean> | Observable<boolean>
// custom logic goes here too
return parentCanActivate && customCondition;
}
}