Nestjs RBAC 权限控制管理实践 (二)

栏目: 编程工具 · 发布时间: 5年前

内容简介:接上回分析了 node-casbin 模块, Casbin 主要是提供了多种的权限控制策略, 支持 ACL, RBAC, ABAC, RESTful 以及复杂的拒绝覆盖, 权限优先等级等。 不得不说 Casbin 功能强大,不过对于我的项目需求,直接用起来,看似又比较复杂了。 因为我这个项目主要是用RESTful API, 所以借鉴了 accesscontrol 和 casbin 的 RESTful 的控制模式简化成我要的版本,具体如下:上回我们看官网的方式是,使用 @RolesGuard 和 @Roles

Nestjs RBAC 权限控制管理实践 (一)

上回分析了 node-casbin 模块, Casbin 主要是提供了多种的权限控制策略, 支持 ACL, RBAC, ABAC, RESTful 以及复杂的拒绝覆盖, 权限优先等级等。 不得不说 Casbin 功能强大,不过对于我的项目需求,直接用起来,看似又比较复杂了。 因为我这个项目主要是用RESTful API, 所以借鉴了 accesscontrol 和 casbin 的 RESTful 的控制模式简化成我要的版本,具体如下:

1. @RolesGuard 与 @Roles 的关系

上回我们看官网的方式是,使用 @RolesGuard 和 @Roles 组合的方式, 使用 @RolesGuard 去守护, @Roles 则去标记哪个角色可以通过。

我们回顾下代码 @RolesGuard 搭档 @Roles

@Controller('cats')
@UseGuards(RolesGuard)
@UseInterceptors(LoggingInterceptor, TransformInterceptor)
export class CatsController {
  constructor(private readonly catsService: CatsService) {}
  @Post()
  @Roles('admin')
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }
}
复制代码

2. AuthGuard 是如何实现的,为什么能带参数。

由于注意到常用的 AuthGuard('jwt') 是又参数的, 但是 RolesGuard 是没有参数的, 也无法带上参数, 所以特地去翻了下 AuthGuard 的源代码. auth.guard.ts

export const AuthGuard: (type?: string) => Type<IAuthGuard> = memoize(
  createAuthGuard
);

function createAuthGuard(type?: string): Type<CanActivate> {
  class MixinAuthGuard<TUser = any> implements CanActivate {
    ...
  }
}

复制代码

3. RESTFul 的动作匹配

对比 AuthGuard 发现其是比较特殊的函数方式返回一个 CanActivate 的实现类, 这个实现比较复杂,同时也失去了依赖注入的能力。 并且由于项目需求是由界去配置权限和 API 的关联关系的,所以这里并不能直接用角色去关联API。 还有另外一个原因是 RESTFul 的 API 可以采用约定的规则来匹配权限,所以并不必要每个 API 去打标记, 匹配形式为 :

{
  GET: 'read', // 读取
  POST: 'create', // 创建
  PUT: 'update',  // 更新
  DELETE: 'delete', // 删除
}
复制代码

4. @RolesGuard 如何得到控制器的注解信息(这个花了点时间搞出来)

经过上面的处理, 我们在控制器上可以解放出来了,我们只要一个 @RolesGuard, 并不要 @Roles 来配合了。

但由于 @RolesGuard 无法传递控制器参数, 所以我们只能另寻办法了, 想到 @RolesGuard 能获取到 @Roles 里注解参数, 我们是不是能从 @Controller 里获得参数呢? 这样我们就能定位当前的请求资源了,于是有了下面的代码: 最终代码

async canActivate(context: ExecutionContext): Promise<boolean> {
 
     const roles = this.reflector.get<string[]>(
       'roles',
        context.getHandler(),
     ); // 这里我们能从 context.getHandler() 里得到 roles;

    /** 那么我们也就能从  context.getClass() 里得到 @Controller 里的注解参数,
     当然,我们也能从 request.url 里分析得到,但是控制器的注解有时候可能写的复杂 如 abc/efg 我们就不知道怎么截断了。
    **/
    const ctrl = this.reflector.get<string>('path', context.getClass());  
    ...
  }

复制代码

5. 关联 API 到菜单。

我写了一个 API 的描述文件

const actions = {
  create: '创建',
  read: '读取',
  update: '更新',
  delete: '删除',
};

export interface GrantNode {
  name: string;
  actions: {
    [k: string]: string;
    create?: string;
    read?: string;
    update?: string;
    delete?: string;
  };
}

export const grants: {
  [key: string]: GrantNode;
} = {
  dict: {
    name: '字典',
    actions,
  },
  group: {
    name: '用户组',
    actions,
  },
  log: {
    name: '日志',
    actions,
  },
  menu: {
    name: '菜单',
    actions,
  },
  notice: {
    name: '通知',
    actions,
  },
  role: {
    name: '角色',
    actions,
  },
  setting: {
    name: '设置',
    actions,
  },
  user: {
    name: '用户',
    actions,
  },
};

复制代码

以上所述就是小编给大家介绍的《Nestjs RBAC 权限控制管理实践 (二)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Using Google App Engine

Using Google App Engine

Charles Severance / O'Reilly Media / 2009-5-23 / USD 29.99

With this book, you can build exciting, scalable web applications quickly and confidently, using Google App Engine - even if you have little or no experience in programming or web development. App Eng......一起来看看 《Using Google App Engine》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

MD5 加密
MD5 加密

MD5 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试