nestjs-rbac

Awesome RBAC for NestJs
授权协议 View license
开发语言 JavaScript
所属分类 Web应用开发、 常用JavaScript包
软件类型 开源软件
地区 不详
投 递 者 宗波涛
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

RBAC CIRBAC CD

Description

The rbac module for Nest.

Installation

npm i --save nestjs-rbac

Quick Start

For using RBAC there is need to implement IStorageRbac

export interface IStorageRbac {
  roles: string[];
  permissions: object;
  grants: object;
  filters: { [key: string]: any | IFilterPermission };
}

For instance:

export const RBACstorage: IStorageRbac = {
  roles: ['admin', 'user'],
  permissions: {
    permission1: ['create', 'update', 'delete'],
    permission2: ['create', 'update', 'delete'],
    permission3: ['filter1', 'filter2', RBAC_REQUEST_FILTER],
    permission4: ['create', 'update', 'delete'],
  },
  grants: {
    admin: [
      '&user',
      'permission1',
      'permission3',
    ],
    user: ['permission2', 'permission1@create', 'permission3@filter1'],
  },
  filters: {
    filter1: TestFilterOne,
    filter2: TestFilterTwo,
    [RBAC_REQUEST_FILTER]: RequestFilter,
  },
};

Storage consists of the following keys:

roles: array of roles

permissions: objects of permissions which content actions

grants: objects of assigned permission to roles

filters: objects of customized behavior

Grant symbols

&: extends grant by another grant, for instance admin extends user (only support one level inheritance)

@: a particular action from permission, for instance permission1@update

Using RBAC like an unchangeable storage

import { Module } from '@nestjs/common';
import { RBAcModule } from 'nestjs-rbac';

@Module({
  imports: [
    RBAcModule.forRoot(IStorageRbac),
  ],
  controllers: []
})
export class AppModule {}

Using RBAC like a dynamic storage

There is enough to implement IDynamicStorageRbac interface.

import { Module } from '@nestjs/common';
import { RBAcModule } from 'nestjs-rbac';

@Module({
  imports: [
    RBAcModule.forDynamic(DynamicStorageService),
  ],
  controllers: []
})
export class AppModule {}
// implement dynamic storage
import { IDynamicStorageRbac, IStorageRbac } from 'nestjs-rbac';
@Injectable()
export class  DynamicStorageService implements IDynamicStorageRbac {
  constructor(
    private readonly repository: AnyRepository
  ) {

  }
  async getRbac(): Promise<IStorageRbac> {
//use any persistence storage for getting `RBAC`
      return  await this.repository.getRbac();
  }
}

Using for routers

import { RBAcPermissions, RBAcGuard } from 'nestjs-rbac';

@Controller()
export class RbacTestController {

  @RBAcPermissions('permission', 'permission@create')
  @UseGuards(
// Any Guard for getting & adding user to request which implements `IRole` interface from `nestjs-rbac`:
//*NOTE:
//  const request = context.switchToHttp().getRequest();
//  const user: IRole = request.user;
    GuardIsForAddingUserToRequestGuard,
    RBAcGuard,
  )
  @Get('/')
  async test1(): Promise<boolean> {
    return true;
  }
}

Using for a whole controller

It's applicable with the crud library, for example nestjsx/crud

import { RBAcPermissions, RBAcGuard } from 'nestjs-rbac';

@Crud({
	model: {
		type: Company,
	},
})
@RBAcPermissions('permission2')
@UseGuards(
		AuthGuard,
		RBAcGuard,
)
@Controller('companies')
export class CompaniesController implements CrudController<Company> {
	constructor(public service: CompaniesService) {}
}

one more example

@Crud({
	model: {
		type: Company,
	},
	routes: {
		getManyBase: {
			interceptors : [],
			decorators: [RBAcPermissions('permission1')],
		},
		createOneBase: {
			interceptors : [],
			decorators: [RBAcPermissions('permission2')],
		},
	},
})
@UseGuards(
		AuthGuard,
		RBAcGuard,
)
@Controller('companies')
export class CompaniesController implements CrudController<Company> {
	constructor(public service: CompaniesService) {
	}
}

Using like service

import { RbacService } from 'nestjs-rbac';

@Controller()
export class RbacTestController {

  constructor(
    private readonly rbac: RbacService
  ){}

  @Get('/')
  async test1(): Promise<boolean> {
    return await (await this.rbac.getRole(role)).can('permission', 'permission@create');
    return true;
  }
}

Using the custom filters

filter is a great opportunity of customising behaviour RBAC.For creating filter, there is need to implement IFilterPermission interface, which requires for implementing can method, and bind a key filter with filter implementation, like below:

export const RBAC: IStorageRbac = {
  roles: ['role'],
  permissions: {
    permission1: ['filter1', 'filter2'],
  },
  grants: {
    role: [
      `permission1@filter1`
      `permission1@filter2`
    ],
  },
  filters: {
    filter1: TestFilter,
    filter2: TestAsyncFilter,
  },
};
//===================== implementing filter
import { IFilterPermission } from 'nestjs-rbac';

export class TestFilter implements IFilterPermission {

  can(params?: any[]): boolean {
    return params[0];
  }

}

//===================== implementing async filter
import { IFilterPermission } from 'nestjs-rbac';

@Injectable()
export class TestAsyncFilter implements IFilterPermission {
  constructor(private readonly myService: MyService) {}

  async canAsync(params?: any[]): Promise<boolean> {
    const myResult = await this.myService.someAsyncOperation()
    // Do something with myResult
    return myResult;
  }
}

⚠️ - A single filter can implement both can and canAsync. If you use the RBAcGuard, they will be evaluated with an AND condition.

ParamsFilter services for passing arguments into particular filter:

const filter = new ParamsFilter();
filter.setParam('filter1', some payload);

const res = await (await rbacService.getRole('admin', filter)).can(
  'permission1@filter1',
);

Also RBAC has a default filter RBAC_REQUEST_FILTER which has request object as argument:

Example:
//===================== filter
export class RequestFilter implements IFilterPermission {

  can(params?: any[]): boolean {
    return params[0].headers['test-header'] === 'test';
  }
}
//===================== storage
export const RBAC: IStorageRbac = {
  roles: ['role'],
  permissions: {
    permission1: ['filter1', 'filter2', RBAC_REQUEST_FILTER],
  },
  grants: {
    role: [
      `permission1@${RBAC_REQUEST_FILTER}`
    ],
  },
  filters: {
    [RBAC_REQUEST_FILTER]: RequestFilter,
  },
};
//===================== using for routes
  @RBAcPermissions(`permission1@${RBAC_REQUEST_FILTER}`)
  @UseGuards(
    AuthGuard,
    RBAcGuard,
  )
  @Get('/')
  async test4(): Promise<boolean> {
    return true;
  }

Performance

By default, RBAC storage always parses grants for each request, in some cases, it can be a very expensive operation.The bigger RBAC storage, the more taking time for parsing. For saving performance RBAC has built-in a cache, based on node-cache

Using cache

import { RbacCache } from 'nestjs-rbac';

@Module({
  imports: [
    RBAcModule.useCache(RbacCache, {KEY: 'RBAC', TTL: 400}).forDynamic(AsyncService),
  ],
})

if you need to change a cache storage, there is enough to implement ICacheRBAC

ICacheRBAC

export interface ICacheRBAC {
  KEY: string;
  TTL: number;

  get(): object | null;

  /**
   *
   * @param value
   */
  set(value: object): void;

  del(): void;
}

Inject ICacheRBAC

import { ICacheRBAC } from 'nestjs-rbac';
...
@Inject('ICacheRBAC') cache: ICacheRBAC
  • 文章更多的是在于记录。有看不懂的评论 2.1 RBAC 0 https://juejin.cn/post/6844904109863075853#heading-3 最简单的用户、角色、权限模型。这里面又包含了2种: 用户和角色是多对一关系,即:一个用户只充当一种角色,一种角色可以有多个用户担当。 用户和角色是多对多关系,即:一个用户可同时充当多种角色,一种角色可以有多个用户担当。 jwt 依赖包

  • 目前由于在做 Nodejs 构架的迁移, 把原有的 typerx 的后端项目迁移到 NestJS 框架上来, 做到权限管理部分, 特和大家分享下。 项目地址: typerx nestx NestJs 官方角色控制介绍 因为这篇文章主要是对权限管理部分对介绍, 所以暂定已经有了用户身份知识的了解, 若想了解用户登录相关内容, 请参阅其他相关文档。 Guards Guards 是一个注解式的守卫, 他

  • 接 Nestjs RBAC 权限控制管理实践 (一) 上回分析了 node-casbin 模块, Casbin 主要是提供了多种的权限控制策略, 支持 ACL, RBAC, ABAC, RESTful 以及复杂的拒绝覆盖, 权限优先等级等。 不得不说 Casbin 功能强大,不过对于我的项目需求,直接用起来,看似又比较复杂了。 因为我这个项目主要是用RESTful API, 所以借鉴了 acces

 相关资料
  • A collection of Badass modules and utilities to help you level up your NestJS application. Package Description Version Changelog @golevelup/nestjs-common Common types, mixins changelog @golevelup/nest

  • Nestjs-BFF OVERVIEW Overview     Frontend     Backend     CLI     DevOps Status This library is currently 'on ice' and is no longer being activley maintained at this time. However, it may still server

  • rucken-core-nestjs A simple application demonstrating the basic usage of permissions with NestJS (JWT, Passport, Facebook, Google+, User, Group, Permission) based on Rucken template Screenshots Featur

  • Nest.js 教程 如果喜欢本教程请点击右上角的 star �� ,想订阅本教程请点击右上角 watch �� 如有不解之惑,或是想要更多的详细教程,可以在 New Issues 中写下你的问题或需求。 框架介绍 Nest 是构建高效,可扩展的 Node.js Web 应用程序的框架。它使用现代的 JavaScript 或 TypeScript(保留与纯 JavaScript 的兼容性),并结合

  • testing-nestjs Status A repository to show off to the community methods of testing NestJS including Unit Tests, Integration Tests, E2E Tests, pipes, filters, interceptors, GraphQL, Mongo, TypeORM, and

  • nestjs-query Nestjs-Query is collection of packages to make crud for graphql easier. Why? While working on projects in nestjs it was very easy to get up and running with graphql however, there were ma