【问题标题】:Django Graphene/GraphQL best design for model field-level permissionsDjango Graphene/GraphQL 模型字段级权限的最佳设计
【发布时间】:2021-07-29 22:04:20
【问题描述】:

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

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

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

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

  1. 在 graphene-django DjangoObjectType 中覆盖 get_node 解析器以检查那里的权限。我个人认为这是一个非常糟糕且不得已的解决方案,因为检查仅在 graphql 查询/突变层上完成,而不是在 Django 的其他地方。我可以轻松编写一个不会从权限检查中受益的 Django 表单或视图,除非在该表单/视图中再次对其进行编码。

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

我想知道是否有人对解决此问题的最佳方法有看法,该方法适合 Django 和 Graphene 框架,并且无需在任何地方重复权限代码?

【问题讨论】:

    标签: django graphene-django


    【解决方案1】:

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

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

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

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

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

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

    这样,您可以使用标准的内置权限来拒绝访问整个表格(如上图所示)和对象级别权限(GuardianAuthority)来拒绝除当前医生之外的所有人访问真正机密的内容.

    希望这会有所帮助,祝你好运!

    【讨论】:

    • 谢谢 - 这真的很有帮助,也符合我的想法!感觉根据权限拆分对象是最简单的方法
    猜你喜欢
    • 1970-01-01
    • 2013-12-22
    • 2015-01-28
    • 1970-01-01
    • 2012-04-28
    • 2013-05-15
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多