首页 > 解决方案 > 如何使用 Postgraphile 或替代方案在 Postgres 中实现复杂的基于权限的数据访问

问题描述

对于一个新项目,我们目前正在设计一个数据库和一个 API 来访问它。我们已经确定我们将使用 PostgresQL 作为数据库,并希望通过 GraphQL API 访问它。

为了简化可维护性,我们研究了客户端/API/数据库之间的几个中介,主要是 Prisma、PostGraphile 和 Hasura。PostGraphile 脱颖而出,因为它易于使用,并且专注于处理“在数据库中”而不是在后端代码中的内容。但是,在弄清楚如何实现这一点时,我们遇到了问题。

请允许我扩展我们迄今为止的设计:


临时数据库设计:

数据权限:

我们希望用户通过几个步骤授予其他人访问其个人数据的权限,最好是针对每个组。例如:

如果可以为各种类型的数据设置此项,那就太棒了,例如为您的电话号码授予第 2 级,但为您的实际地址授予第 1 级。因此,这些级别(1、2、3)将伴随数据库中的数据,例如phone_numberphone_number_access_level。然后,在联结表中,//u_g_r的每个组合都会附加一个允许的级别,该级别必须高于相关数据所需的级别。因此,如果您允许访问级别 2 上的数据,您将能够查看级别 1 和级别 2 上的数据,但不能查看级别 3。usergrouprolerole


Postgres 允许列和行级别的安全性,让用户访问某些数据。PostGraphile wiki 详细介绍了(此处此处)如何使用 JWT 声明而不是 PostGres 角色来完成这项工作。当我们想要实现上述功能时,我们的问题就来了。似乎我们想要一种不存在的“现场级安全”,但我无法想象其他人没有遇到同样的问题。

你会建议我们做什么?请让我知道是否有我们遗漏的选项,或者是否有其他更适合我们的选项!

在数据库之外,在后端代码中实现这一点可能是最简单的方法,但它极大地影响了我们的可维护性,因为像 PostGraphile 这样的东西对我们来说主要的奢侈是消除了我们自己编写 GraphQL 模式和解析器的需要。

标签: postgresqlgraphqlprismahasurapostgraphile

解决方案


根据 Laurenz Albe 的回答,我为各种列创建了一个巨大的视图。它确实有效,即使有数千个模拟数据条目,它仍然相对较快。

当我上周回到它时,我想到了一个更清洁的解决方案(可以说)。我现在不是使用像这样的自定义视图,而是使用带有敏感数据的单独表,将它们与外键链接并在这些行上启用行级别安全性。

我没有做任何基准测试,但它应该更快,因为无论如何并不总是要求这些数据。它至少可以节省大量样板文件的复杂视图!


推荐阅读