繁体   English   中英

GraphQL 后端的 RBAC 使用 CASL 和 graphql-shield 并与我的 React 前端共享规则

[英]RBAC on GraphQL backend using CASL and graphql-shield and sharing rules with my React front-end

我正在运行 Mongoose 并使用 GraphQL (Apollo) 公开 API。

我想实现一个 RBAC,经过一些研究,我提出了一个使用 CASL 和 graphql-shield 的解决方案。 理想情况下,我想与我的 React 前端共享规则。


第一步,在一张纸上计划。

我会首先定义我的操作:创建、读取、更新、删除。

然后我会定义我的主题:汽车、摩托车。

完成后,我将继续定义我的角色:CarSpecialist、MotoSpecialist、Admin。 然后我会定义一些条件:“主题是我自己的”等。

最后,我会为每个角色分配一组能力(动作、主题、条件的组合)。


现在完成所有这些,我开始实际编写我的解决方案。

我首先在 CASL 中编写能力:动作和主题很容易定义。

条件有点棘手,我至少有两个选择:

  • 我使用“模糊”的概念,而这些概念又必须由执行它们的任何需要(后端或前端)来解释。

  • 我使用 CASL mongoose 集成插件,代价是失去与我的前端共享的能力。


有什么可供选择的输入吗?

现在一旦定义了 CASL 能力,是否由 graphql-shield 来强制执行它们?

如何在 (CASL) 操作、主题和条件与 graphql 术语之间进行映射:模式、查询、突变...?

我会尽量回答这个问题:

  1. 如果使用默认条件,您不会失去与 UI 共享权限的能力。 运行ability.can .can 时,条件在 js 中解释。 因此,如果 mongo 查询语言适合您,则无需更改!
  2. Graphql shield是一种特殊的graphql中间件。 如果您使用 casl 和 graphql 中间件,则不需要 graphql 屏蔽! 使用 casl + 自定义 graphql 中间件或 graphql-shield
  3. 每个 graphql 类型都有底层源类型。 源类型基本上是您的域 model 或只是封装业务逻辑的 db model。 这是您的映射:) 只需检查源类型的权限即可。 但是,如果您与 UI 共享权限,则需要将针对源类型编写的后端权限(在发送到 UI 之前)转换为可应用于 graphql 类型的权限,或者。 您可以公开一些私有道具(例如,汽车的ownerId )作为 graphql 类型的一部分。 但如果这样做的唯一目的是满足权限共享,那么我会 go 与转换选项:
function defineAbility(user, props) {
   const { can, rules} = new AbilityBuilder(Ability)

   can('read', 'Post', { [props.authorId]: user.id })
   // ...

   return rules;
}

const currentUser = { id: 1 }
const backendRules = defineAbility(currentUser, {
  authorId: 'authorId'
});

const uiRules = defineAbility(currentUser, {
  authorId: 'author.id'
});

或者,您可以通过在每个 graphql 类型上公开子类型来检查后端的权限并与前端共享结果:


{
   cars {
     items {
       permissions {
         canUpdate
         canRead
       }
     }
   }
}

这样做的后果是您的服务器将花费更多时间生成响应,尤其是在您检索分页项目时。 因此,在继续之前检查响应时间。 这样做的好处是 UI 上不需要 casl,权限检查逻辑完全隐藏在后端

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM