postgresql - 如何使用 Postgraphile 或替代方案在 Postgres 中实现复杂的基于权限的数据访问
问题描述
对于一个新项目,我们目前正在设计一个数据库和一个 API 来访问它。我们已经确定我们将使用 PostgresQL 作为数据库,并希望通过 GraphQL API 访问它。
为了简化可维护性,我们研究了客户端/API/数据库之间的几个中介,主要是 Prisma、PostGraphile 和 Hasura。PostGraphile 脱颖而出,因为它易于使用,并且专注于处理“在数据库中”而不是在后端代码中的内容。但是,在弄清楚如何实现这一点时,我们遇到了问题。
请允许我扩展我们迄今为止的设计:
临时数据库设计:
users
桌子groups
桌子roles
桌子:u_g_r
表:一个用户可以是多个组的一部分,并且每个组可以有多个角色。该表表示和的外键users
,因为多对多关系几乎可以存在于所有组合中。groups
roles
数据权限:
我们希望用户通过几个步骤授予其他人访问其个人数据的权限,最好是针对每个组。例如:
- 3级:你自己,只有绝对必要的人,比如客户经理
- 2级:只有X、Y等组的人
- 1级:所有人
如果可以为各种类型的数据设置此项,那就太棒了,例如为您的电话号码授予第 2 级,但为您的实际地址授予第 1 级。因此,这些级别(1、2、3)将伴随数据库中的数据,例如phone_number
和phone_number_access_level
。然后,在联结表中,//u_g_r
的每个组合都会附加一个允许的级别,该级别必须高于相关数据所需的级别。因此,如果您允许访问级别 2 上的数据,您将能够查看级别 1 和级别 2 上的数据,但不能查看级别 3。user
group
role
role
Postgres 允许列和行级别的安全性,让用户访问某些数据。PostGraphile wiki 详细介绍了(此处和此处)如何使用 JWT 声明而不是 PostGres 角色来完成这项工作。当我们想要实现上述功能时,我们的问题就来了。似乎我们想要一种不存在的“现场级安全”,但我无法想象其他人没有遇到同样的问题。
你会建议我们做什么?请让我知道是否有我们遗漏的选项,或者是否有其他更适合我们的选项!
在数据库之外,在后端代码中实现这一点可能是最简单的方法,但它极大地影响了我们的可维护性,因为像 PostGraphile 这样的东西对我们来说主要的奢侈是消除了我们自己编写 GraphQL 模式和解析器的需要。
解决方案
根据 Laurenz Albe 的回答,我为各种列创建了一个巨大的视图。它确实有效,即使有数千个模拟数据条目,它仍然相对较快。
当我上周回到它时,我想到了一个更清洁的解决方案(可以说)。我现在不是使用像这样的自定义视图,而是使用带有敏感数据的单独表,将它们与外键链接并在这些行上启用行级别安全性。
我没有做任何基准测试,但它应该更快,因为无论如何并不总是要求这些数据。它至少可以节省大量样板文件的复杂视图!
推荐阅读
- python - .get_object() 显示数据集而不是模型中的字段数据
- azure - 什么是好的 Databricks 工作流程
- firebase - Firebase Auth - ConfirmPasswordReset,如何从 URL 中获取 oobcode 以通过函数?
- mime-types - .gem 文件的 myme 类型是什么?
- ffmpeg - 如果流编码是 rawvideo,如何按流方式转换 mkv 文件?
- python - TypeError:描述符“isoformat”需要一个“datetime.date”对象但收到一个“str”
- python - 加载 epochs 日志 Keras 模型
- python - 使用 openpyxl 应用 Excel 公式
- python - Return next element of a list at every loop for a loading screen
- javascript - componentDidUpdate 警告:已安排级联更新