【问题标题】:NestJS - how to check if JWT can access specific endpointNestJS - 如何检查 JWT 是否可以访问特定端点
【发布时间】:2021-01-27 05:37:45
【问题描述】:

假设我有 3 个端点:A 用于生成 JWT 令牌,B 用于访问用户 X 的数据,C 用于访问用户 Y 的数据。现在,我想要做的是,我可以以某种方式从收到的令牌中控制器看守弄清楚,如果用户可以访问端点。

所以,为用户 X 生成的令牌只能访问端点 B,为用户 Y 生成的令牌只能访问端点 C。

令牌必须在端点 A 生成,因为用户以相同的形式登录。 如果问题不清楚,请在评论中提问。

【问题讨论】:

  • 问题是什么?就像您是否试图让经过身份验证的用户访问特定端点,或者您是否正在查看该用户的特定质量以确定他们是否有权访问路由。
  • @HenryLy 根据帐户类型,我希望用户仅访问特定端点。
  • 如何将帐户添加到 JWT,如果您这样做的话。还是 JWT 只是与用户 ID 一致?您如何在规则中规定某些帐户应该或不应该激活某些路由?
  • 在 JWT 有效负载上添加一个角色,然后使用装饰器 @SetMetadata() 在每个端点上分配角色,如果允许用户访问该端点,您可以使用反射器检查您的警卫。
  • @JuanRambal 这行得通,SetMetadata 结果证明是最干净的解决方案。谢谢!

标签: node.js jwt nestjs


【解决方案1】:

您可以通过在有效负载中指定一个角色来做到这一点,通过这个角色,您可以在每个端点上设置一个保护,哪个角色可以访问它。我举个例子:

我相信你有一个函数可以填充你的 payload 这种函数:

    createJwtPayload(user){
    let data: JwtPayload = {
        userData: user,
        companyId : user.company.id,
        role:user.role.name, // for us this where we specify the role for our User
    };

   ......
}

现在我们必须创建需要为 x 个端点指定访问权限的守卫
让我们从 Admin Guard 开始:

    @Injectable()
            export class AdminGuard implements CanActivate {
        async canActivate(context: ExecutionContext): Promise<boolean> {
         const request = context.switchToHttp().getRequest();
   
      if (!request.headers.authorization) {
        return false;
      }
      request.user = await this.validateToken(request.headers.authorization);
       if( request.user.role == ROLES.SUPER_ADMIN) {
          return true;
        }
       return false;
             }

         async validateToken(auth: string) {
            ......
      }  

让我们做第二个后卫,我们称之为EmployeGuard

 ....
@Injectable()
export class EmployeGuard implements CanActivate {
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
   
      if (!request.headers.authorization) {
        return false;
      }
      request.user = await this.validateToken(request.headers.authorization);
         if( request.user.role == ROLES.COMPANY_ADMIN ||  request.user.role == ROLES.USER) {
          return true;
        }
       return false;
  }

  async validateToken(auth: string) {
    ......
}

现在要使用这些防护,我们只需要在端点中使用 @UseGuards() 即可:

      @Post()
    @UseGuards(AdminGuard)
    async addCompany(@Res() res, @Body() createDto: CompanyDto) {
      ........
    }

   @Get(':companyID')
    @UseGuards(EmployeGuard)
    async getcompany(@Res() res, @Param('companyID') companyID) {
       ....
     }

奖励:您可以在控制器上@useGuards 以确保所有端点都使用它

【讨论】:

  • 将其与 Juan 的 SetMetadata 解决方案一起使用,谢谢!
猜你喜欢
  • 2015-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 2015-02-05
  • 1970-01-01
  • 2011-02-18
  • 1970-01-01
相关资源
最近更新 更多