对于一个新项目,我们目前正在设计一个数据库和一个 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 模式和解析器的需要。