The rbac module for Nest.
npm i --save nestjs-rbac
For using RBAC
there is need to implement IStorageRbac
export interface IStorageRbac {
roles: string[];
permissions: object;
grants: object;
filters: { [key: string]: any | IFilterPermission };
}
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,
},
};
roles
: array of roles
permissions
: objects of permissions which content actions
grants
: objects of assigned permission to roles
filters
: objects of customized behavior
&
: extends grant by another grant, for instance admin
extends user
(only support one level inheritance)
@
: a particular action from permission, for instance permission1@update
import { Module } from '@nestjs/common';
import { RBAcModule } from 'nestjs-rbac';
@Module({
imports: [
RBAcModule.forRoot(IStorageRbac),
],
controllers: []
})
export class AppModule {}
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();
}
}
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;
}
}
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) {}
}
@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) {
}
}
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;
}
}
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;
}
}
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:
//===================== 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;
}
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
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
export interface ICacheRBAC {
KEY: string;
TTL: number;
get(): object | null;
/**
*
* @param value
*/
set(value: object): void;
del(): void;
}
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