Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何根据Graphene/Django上的用户类型限制模型上的字段访问?_Python_Django_Graphene Python - Fatal编程技术网

Python 如何根据Graphene/Django上的用户类型限制模型上的字段访问?

Python 如何根据Graphene/Django上的用户类型限制模型上的字段访问?,python,django,graphene-python,Python,Django,Graphene Python,假设我有一个模型: class Employee(models.Model): first_name = models.CharField(max_length=40) last_name = models.CharField(max_length=60) salary = models.DecimalField(decimal_places=2) 我希望任何人都能够访问名字和姓氏,但只希望某些用户能够读取工资,因为这是机密数据 然后我想限制写/更新工资给一个甚至不同类

假设我有一个模型:

class Employee(models.Model):
    first_name = models.CharField(max_length=40)
    last_name = models.CharField(max_length=60)
    salary = models.DecimalField(decimal_places=2)
我希望任何人都能够访问名字和姓氏,但只希望某些用户能够读取工资,因为这是机密数据

然后我想限制写/更新工资给一个甚至不同类型的用户

如何根据请求用户限制字段读/写/更新

编辑:

这在GraphQLAPI上下文中。我用的是石墨烯。我想在解析器函数中看到一个可伸缩的解决方案

询问 假设你有

  • 定义如下的查询

    employees=石墨烯列表(EmployeeType)

  • 查询的解析程序,如

    def resolve_员工(自我、信息、**kwargs): return Employee.objects.all()

  • 您的员工模型的权限称为
    可以查看工资
    可以编辑工资
  • 然后您需要定义
    EmployeeType
    ,其值为
    salary
    ,具体取决于用户。差不多

    from graphene_django.types import DjangoObjectType
    from myapp.models import Employee
    
    class EmployeeType(DjangoObjectType):
        class Meta:
            model = Employee
            
        def resolve_salary(self, info):
            if info.context.user.has_perm('myapp.can_view_salary'):
                return self.salary
            return None
    
    重要的一点是,您正在为基于权限值切换的薪资创建一个自定义的
    resolve
    函数。您不需要为
    first\u name
    last\u name
    创建任何其他解析程序




    突变 但是没有一个更新的例子

    简而言之,以下是您可以采取的方法:

  • 创建一个方法,在
    方法中设置员工

    类别MyTranslations(graphene.ObjectType): set_employee=SetEmployee.Field()

  • SetEmployee
    创建一个方法,该方法获取并更新Employee对象。对于某些用户,薪资字段被忽略。再次注意,我将字符串作为输入,从而忽略了十进制问题

    类别SetEmployee(石墨烯突变):


  • 伟大的回应@MarkChackerian。然而,就我个人而言,我认为在未经授权的访问中为字段返回null值可能是不明确的,因此我个人从resolve方法中提出了一个异常,如下所示:

    class UnauthorisedAccessError(GraphQLError):
        def __init__(self, message, *args, **kwargs):
            super(UnauthorisedAccessError, self).__init__(message, *args, **kwargs)
    
    def resolve_salary(self, info):
            if info.context.user.has_perm('myapp.can_view_salary'):
                return self.salary
            raise UnauthorisedAccessError(message='No permissions to see the salary!')
    

    最好也是最简单的建议是,您需要创建一个组,然后添加自定义权限,并将特定成员包括到该组中。我想了解您如何访问来自reducer的请求,如何在带有未授权字段的查询中发送错误,以及如何在reducer中处理身份验证。问题更多的是认证的GraphQL集成,而不是Django端。当你说“reducer”时,你是指React/Redux意义上的“reducer”,还是指“resolver”?是的,是resolver,我的错。这个问题有两个部分,因为graphenepython实现需要单独的读(即查询)和写(即突变)功能,这取决于用例。如果用户正在编写自己的查询,那么最好引发一个异常,如您所示。但是,我认为更常见的用例是graphQL查询嵌入到javascript中,在这种情况下,使用一个graphQL查询来处理两类用户(具有访问权限的用户和没有访问权限的用户)更为实际。如果你提出一个例外,你不能有一个单一的查询同时适用于这两种用户。这似乎违反了我的直觉。通过定义像上面的
    resolve\u salary()
    这样的函数,我们实际上是在创建一个不允许用户查看的字段黑名单。将来在
    Employee
    模型中添加一个新的特权字段,开发人员不可避免地忘记创建
    resolve\u newfield()
    函数来限制其访问时,这可能会很麻烦。因此,忘记定义函数会造成安全漏洞。-有没有一种方法可以阻止所有字段,除非我们显式允许它(而不是显式阻止它)?@PKKid似乎有一些方法可以在源代码中显式限制字段,但据我所知,它们没有文档记录,并且它们不允许基于条件的访问谢谢。它没有正式的文档记录,但是bugs中的这个讨论讨论讨论了在查询中引用的唯一的_字段。光是讨论就让我对提前使用它感觉好一点。
    class UnauthorisedAccessError(GraphQLError):
        def __init__(self, message, *args, **kwargs):
            super(UnauthorisedAccessError, self).__init__(message, *args, **kwargs)
    
    def resolve_salary(self, info):
            if info.context.user.has_perm('myapp.can_view_salary'):
                return self.salary
            raise UnauthorisedAccessError(message='No permissions to see the salary!')