Django Graphene/GraphQL 模型字段级权限的最佳设计

Django Graphene/GraphQL best design for model field-level permissions

我使用 Django 作为后端,使用 graphene-django 作为前端。我是 django 和 graphene 的新手,所以我不确定在这个设置中没有代码重复的情况下实现字段级权限的最佳方法是什么。例如,如果我的模型是:

class MyModel(models.Model):
   field1 = models.CharField()
   field2 = models.CharField()

我希望能够指定 user1 可以读取 field1 但不能 field2;当 user1 为所有 MyModels 查询 GraphQL 时,它只允许从行(节点)而不是 field2 中检索 field1。

我做了一些研究,发现了 2 个可能的替代解决方案,但我担心它们可能不符合 Django 框架的精神 and/or 相互冲突,可能有更好的方法来实现这一点姜戈。最后,我不想在 Django 和 Graphene 后端的多个部分重复权限代码,因此希望将其集中在尽可能低的级别,最好是在 Django 模型中。我需要能够根据 user_id 控制每个字段的完整 CRUD,甚至可能有一些额外的逻辑。我找到的选项是:

  1. 覆盖 get_node graphene-django DjangoObjectType 中的解析器以检查那里的权限。我个人认为这是一个非常糟糕的最后手段解决方案,因为检查仅在 graphql query/mutation 层上完成,而不是在 Django 的其他地方。我可以很容易地编写一个不会从权限检查中受益的 Django 表单或视图,除非在 form/view.

    中再次编码
  2. 我可以扩展 Django 模型以执行任意的每个字段检查,这似乎是执行权限检查的正确级别,但理想情况下我更愿意使用内置功能或 'popular' 这类东西的库。我尝试搜索一个库,但我找不到任何可以远程生产或获得任何牵引力的东西——这让我想到可能有更好的方法来解决这个问题。 Django-field-permissions 包似乎在正确的道路上。

我想知道是否有人对解决适合 Django 和 Graphene 框架且无需到处重复权限代码的问题的最佳方法有看法?

您不会为此找到 stable/popular 包,因为它不是数据库可以很好支持的设计。

您不能 link(外键)一个字段和一个 table,您只能 link 两个 table 使用一个字段。因此,任何确定 table 中的行是否可以访问另一个 table 中的字段的工作都将代价高昂且容易出错。

您能做的最好的事情就是编写一个位于解析器和模型之间的服务层,该模型使用户无法访问的字段无效。您将用户 (info.context.user) 和模型传递给它,它会单独查询字段权限模型,获取记录并根据权限取消每个字段。

这本质上意味着每个字段都需要可以为空才能支持权限,从而使前端复杂化 - 这需要大量工作...

如果您的业务逻辑允许,更好的方法是将这些字段分组到模型中,然后可以将其绑定到“角色”或组。因此,如果这是医院的医疗数据:

- name  ----- \
- address     | -> Person model => all personnel, except custodial
- birth date -/
- medication -------\
- patient history   | => PatientStatus model => all medically trained personnel
- current physician /
- ...

这样你就可以使用标准的内置权限来拒绝访问整个 tables(如上图所示)和对象级别权限 (Guardian, Authority) 来拒绝除当前医生以外的所有人的访问对于真正机密的东西。

希望这对您有所帮助,祝您好运!