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

Posted

技术标签:

【中文标题】使用 CASL 和 graphql-shield 在 GraphQL 后端上的 RBAC 并与我的 React 前端共享规则【英文标题】:RBAC on GraphQL backend using CASL and graphql-shield and sharing rules with my React front-end 【发布时间】:2021-04-12 03:35:10 【问题描述】:

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

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


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

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

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

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

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


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

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

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

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

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


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

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

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

【问题讨论】:

【参考方案1】:

我会尽量回答这个问题:

    如果使用默认条件,您不会失去与 UI 共享权限的能力。当您运行ability.can 时,条件会在 js 中解释。因此,如果 mongo 查询语言适合您,则无需更改! Graphql shield 是一种特殊的graphql 中间件。如果您使用 casl 和 graphql 中间件,您不需要 graphql shield! 使用 casl + 自定义 graphql 中间件或 graphql-shield 每个 graphql 类型都有底层源类型。源类型基本上是您的域模型或只是封装业务逻辑的数据库模型。这是您的映射 :) 只需检查源类型的权限即可。但是,如果您与 UI 共享权限,那么您需要将针对源类型编写的后端权限(在发送到 UI 之前)转换为可以应用于 graphql 类型的权限!或者,您可以公开一些私有道具(例如,汽车的 ownerId)作为 graphql 类型的一部分。但如果这样做的唯一目的是满足权限共享,那么我会选择转换选项:
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,权限检查逻辑完全隐藏在后端

【讨论】:

以上是关于使用 CASL 和 graphql-shield 在 GraphQL 后端上的 RBAC 并与我的 React 前端共享规则的主要内容,如果未能解决你的问题,请参考以下文章

使用 vuejs 和 laravel 的权限和角色

第9章 用Java,Lua,Python和REST API开发基于SAS Viya的应用:SAS Viya开放平台介绍

GraphQL 实现“不允许”

Graphql shield 返回 Not Authorized for allowed mutation

使用java加密和解密密码使用啥API和算法

如何使用 php 和 mysql 使用纬度和经度进行几何搜索