nestjs - 使用警卫/装饰器的身份验证和角色:如何传递用户对象?
问题描述
在 Guards/Decorators 的帮助下,我尝试先检查 JWT,然后再检查用户的角色。
我已经阅读了关于 Authentication、Guards 和 Decorators 的文档并理解了它们背后的原理。
但是,我不能做的是以某种方式使来自 JWT-Guard 的经过身份验证的用户对 Roles-Guards 可用。
在我发现的每个示例中,正是这对我感兴趣的部分被跳过/遗漏了......
感谢每一个提示!
这是我最近的尝试:
jwt.strategy.ts
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { JwtPayload } from './jwt.model';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
passReqToCallback: true,
ignoreExpiration: false,
secretOrKey: '0000',
expiresIn: '3 days'
});
}
async validate(payload: JwtPayload) {
return {
id: payload.id,
email: payload.email,
username: payload.username
};
}
}
角色.guard.ts
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {
}
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) {
return false;
}
const request = context.switchToHttp().getRequest();
const user = request.user ??? // THIS is what is missing
return roles.some((role) => {
return role === user.role;
});
}
}
角色.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
users.controller.ts
@UseGuards(AuthGuard('jwt'))
@Roles('admin', 'member')
@Get('/')
async doSomething(@Req() req): Promise<User> {
return await this.usersService.doSomething(req.user.id);
}
解决方案
您的装饰器和守卫看起来不错,但从您的users.controller.ts
文件片段中不清楚角色守卫是否实际应用于GET /
路线。
但是,我确实有一个 NestJS 应用程序,其设置非常相似,基于警卫文档。以下代码users.controller.ts
按预期工作:
@UseGuards(JwtAuthGuard, RolesGuard)
@Controller('/users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
@Roles(UserRole.ADMIN)
public async index(): Promise<User[]> {
return this.userService.findAll();
}
// ...
}
请注意 auth 和角色保护是如何在同一范围内激活的,并且是在之前JwtAuthGuard
添加的。如果我要更改守卫的顺序,那么将无法检索请求的用户。 RolesGuard
RolesGuard
此外,您可能想看看前段时间的一个类似问题,其中包含有关不同范围内警卫顺序的一些详细信息。
推荐阅读
- html - html部分背景图片切换
- r - 错误 sh: 1: R/rJava/java: 权限被拒绝
- node.js - Node.js 写入 YAML 文件
- visual-studio-code - 任何让工作区/文件夹设置仅适用于该工作区/文件夹中的文件而不适用于工作区外的随机文件的方法?
- swift - 从子类访问在父类方法内部声明的变量(swift)
- python - 为什么我会收到 ImportError: Cannot import name 'gmap' in python?
- caching - framework7中的当前页面刷新问题
- python - Python“参考技巧”
- java - LinkedList 的复杂流逻辑
- html - 如何在html中重写多个相同的一行div?