RoleGuard 如何在 Nest JS 中工作?智威汤逊

Posted

技术标签:

【中文标题】RoleGuard 如何在 Nest JS 中工作?智威汤逊【英文标题】:How does RoleGuard works in Nest JS? with JWT 【发布时间】:2020-06-29 04:09:44 【问题描述】:

我正在研究的功能是系统应该确定正确的用户类型并在成功登录后允许适当的权限,我想到的是使用 Nest JS 的 RoleGuard 功能。

但我似乎无法弄清楚这个 RoleGuard 是如何工作的。而且似乎无法让它工作。

我想允许具有特定规则的用户访问某些端点,例如只允许具有管理员角色的用户获取所有用户列表。

似乎是什么问题?有人有想法吗?我在下面提供了 sn-ps。根据请求,我是否应该在请求正文中添加角色?或者如果 Ill 获取当前登录的用户并确定角色会很好?谢谢你。 这是我的用户数据,具有以下作用:

"id": 11, 
    "role": "admin",
    "username": "myadmin@test.com",
    "created": "2020-03-18T02:30:04.000Z",
    "updated": "2020-03-18T03:02:12.000Z"

示例代码

 import  JwtAuthGuard  from '../../auth/jwt-auth.guard';
    import  RolesGuard  from '../../common/guards/roles.guard';
    import  Roles  from '../common/decorators/roles.decorator';

    @Controller('user')
    @UseGuards(JwtAuthGuard, RolesGuard)
    export class UserController 
      constructor(private readonly usersService: UsersService) 

      @Get()
      @Roles('admin')
      findAll(): Promise<UserEntity[]> 
        return this.usersService.findAll();
      

角色卫士

 export class RolesGuard implements CanActivate 
      constructor(private readonly reflector: Reflector) 

      canActivate(context: ExecutionContext): boolean 
        const roles = this.reflector.get<string[]>('roles', context.getHandler());
        console.log('roles:', roles);
        if (!roles) 
          return true;
        
        const request = context.switchToHttp().getRequest();
        const user = request.user;
        const hasRole = () => user.roles.some(role => roles.indexOf(role) > -1);
        console.log('hasRole', hasRole);

        return user && user.roles && hasRole();
      
    

【问题讨论】:

【参考方案1】:

要使此代码有效,您需要使用 AuthGuard 将 User obj 添加到请求上下文中。

首先,如果您不实现标准 AuthGuard 所做的其他事情,则不需要 JwtAuthGuard,将 JwtAuthGuard 添加到 UseGuards 装饰器会覆盖默认 AuthGuard,并且如果您不将用户 obj 添加到 JwtAuthGuard 代码内的请求 obj 中, RolesGuard 不能正常工作。

标准方法

如果您看到source code 在第 48 行中,将用户 obj 附加到请求 obj 中。看到这个之后就很简单了.. 只需在@UseGuards 装饰器中添加 AuthGuard('jwt'),RolesGuards 之类的

import  AuthGuard  from '@nestjs/passport';
import  RolesGuard  from '../../common/guards/roles.guard';
import  Roles  from '../common/decorators/roles.decorator';

@Controller('user')
@UseGuards(AuthGuard('jwt'), RolesGuard)
export class UserController 
  constructor(private readonly usersService: UsersService) 

  @Get()
  @Roles('admin')
  findAll(): Promise<UserEntity[]> 
    return this.usersService.findAll();
  

这样做,RolesGuards 的标准方法将正确运行... 现在,如果您做不同的事情并需要自定义 AuthGuard.. 您需要添加 JwtStrategy 类的验证函数返回的用户 Obj。像这样:

import  Injectable, ExecutionContext  from '@nestjs/common';
import  AuthGuard  from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') 
    handleRequest(err: any, user: any, info: any, context: ExecutionContext) 
        const request = context.switchToHttp().getRequest();
        request.user = user;
        return user;
    

【讨论】:

以上是关于RoleGuard 如何在 Nest JS 中工作?智威汤逊的主要内容,如果未能解决你的问题,请参考以下文章

如何让 GLTFLoader 在三个 js 中工作

会话如何在 Express.js 和 Node.js 中工作?

webpack.config.js 如何在 react 项目中工作?

类似 MVC 的代码如何在 Node.js 中工作?

如何使 STATIC_URL 在外部 JS 文件(Django)中工作

如何让 twitter 引导模式在 node js express js 中工作?