Guard 说用户在 NestJS 中未定义
Guard says user is undefined in NestJS
@UseGuards(JwtAccessTokenAuthGuard)
@ApiBearerAuth()
@SetMetadata('roles', Role.ADMIN)
@UseGuards(RolesGuard)
@Post('/add/card')
addCard(@Body() addCardDto: AddCardDto) {
return this.storeService.addCard(addCardDto);
}
这是 RoleGuard
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) {
return true;
}
const user = context.switchToHttp().getRequest().user;
return this.matchRoles(roles, user.user_type);
}
在此,请求对象在正文或函数内部有用户 addCard
但在 RoleGuard
中没有。他们说未定义。为什么这样?在 JwtAccessTokenGuard
我返回了用户 属性.
我想在 Guard 内部检查它,而不是在运行中。我做错了什么。
为了让用户通过这个方法进入守卫:
const user = context.switchToHttp().getRequest().user;
您应该return 本地策略中的用户对象。将 user
对象附加到 request
对象。主体与 user
对象无关。所以,你的 local.strategy.ts 应该是这样的:
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({ usernameField: 'email' });
}
async validate(email: string, password: string): Promise<any> {
const user = await this.authService.validateUser(email, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
有关详细信息,请参阅 here。
当使用两个相同的装饰器时,我记得顺序是代码中最低的装饰器在前,然后是最高的装饰器。在这种情况下,为什么不将两个 @UseGuards()
合并为一个像 @UseGuards(JwtAccessTokenAuthGuard, RolesGuard)
这样的装饰器,这样你就可以确定 运行 在 as described in the docs 中守卫的顺序
@UseGuards(JwtAccessTokenAuthGuard)
@ApiBearerAuth()
@SetMetadata('roles', Role.ADMIN)
@UseGuards(RolesGuard)
@Post('/add/card')
addCard(@Body() addCardDto: AddCardDto) {
return this.storeService.addCard(addCardDto);
}
这是 RoleGuard
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) {
return true;
}
const user = context.switchToHttp().getRequest().user;
return this.matchRoles(roles, user.user_type);
}
在此,请求对象在正文或函数内部有用户 addCard
但在 RoleGuard
中没有。他们说未定义。为什么这样?在 JwtAccessTokenGuard
我返回了用户 属性.
我想在 Guard 内部检查它,而不是在运行中。我做错了什么。
为了让用户通过这个方法进入守卫:
const user = context.switchToHttp().getRequest().user;
您应该return 本地策略中的用户对象。将 user
对象附加到 request
对象。主体与 user
对象无关。所以,你的 local.strategy.ts 应该是这样的:
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({ usernameField: 'email' });
}
async validate(email: string, password: string): Promise<any> {
const user = await this.authService.validateUser(email, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
有关详细信息,请参阅 here。
当使用两个相同的装饰器时,我记得顺序是代码中最低的装饰器在前,然后是最高的装饰器。在这种情况下,为什么不将两个 @UseGuards()
合并为一个像 @UseGuards(JwtAccessTokenAuthGuard, RolesGuard)
这样的装饰器,这样你就可以确定 运行 在 as described in the docs 中守卫的顺序