【问题标题】:permissions checking in serializer, Django rest framework,序列化程序中的权限检查,Django rest 框架,
【发布时间】:2016-09-04 06:01:30
【问题描述】:

我是相当新的 django rest 框架,我对权限有一些疑问。

所以我有一个用户是组织成员和某个组的成员。 假设我们有一个模型:

class SomeModel:
    organization = models.ForeignKey(Organization)
    name = models.CharField()

用户只能为自己的组织create/updateSomeModel,如果他是一组“协调员”,他也可以为任何组织create/update

目前我的方法是在序列化程序中检查这些条件,在.create().update() 方法中,因为数据已经过验证并且我在那里提出PermissionDenied 错误。但感觉这不是“正确的方式”。我尝试制作自定义权限类,但未验证数据,因为在序列化程序之前检查权限类。 你有什么建议我应该如何处理这个问题?

抱歉英语不好,这不是我的母语。 谢谢!

编辑: 例子: 请求数据类似于:

payload = {'organization': 1, 'name': 'Name'} 

因此,如果用户来自组织 1 或者他是协调员,则应授予访问权限并应创建 SomeModel

【问题讨论】:

  • 在使用自定义权限类时,如果用户没有创建/更新权限,为什么还要进一步验证数据?
  • 我需要检查正在创建的模型中的组织是否存在。
  • 我添加了一个例子,这可能有助于理解我的问题...

标签: python django django-rest-framework django-permissions django-serializer


【解决方案1】:

您可以编写自定义权限类HasWritePermissions,它将检查用户是否具有写入/更新权限。

要创建custom permission class,您需要覆盖BasePermission 类并实现has_permission() 方法。如果请求被授予访问权限,此方法应返回True,否则返回False

class HasWritePermissions(BasePermission):

    def has_permission(self, request, view):
        # grant access to non-create/update requests
        if request.method not in ['POST', 'PUT', 'PATCH']:
            return True

        # grant access if user is a member of organization of the object 
        # to be modified or is a coordinator
        if (organization in user.organizations) or (user_is_a_coordinator):
            return True

        # Otherwise don't grant access
        return False 

【讨论】:

  • 为了检查对象的组织,必须先验证请求数据?或者如何获取当前正在创建的对象?
  • 是的,要使用此方法处理创建/更新,您必须使用其 id 查找组织对象并检查其是否在用户的组织中。
  • 但是如果请求有效负载中不存在组织字段或数据库中不存在组织 ID 怎么办。这会导致一些不需要的状态 500 错误......我可以检查所有这些东西,但这就是序列化器和验证器的用途?
  • 你应该做类似的事情,request.data.get('organization_id') in user_organizations_ids 列表或者可能在User 模型上写一个模型方法is_organization_member(organization_id) 相同的。您将使用request.data.get() 传递organization_id 值,该值可以是None 或某个值。然后您可以检查该值是否在用户的organizations id 列表中。您不必担心 organization_id 字段是否存在或是否为有效值。
  • 同意,序列化程序应验证数据,但根据用例,如果“有效”organization_id 不在用户的组织 ID 列表中,则不应授予请求访问权限。此类请求应在权限级别停止。如果organization_id 无效,您可以让请求通过,DRF 序列化程序应该返回 400 错误。(是的,在某种程度上这包括一些重复。)
猜你喜欢
  • 1970-01-01
  • 2017-10-03
  • 2019-05-20
  • 2019-12-23
  • 1970-01-01
  • 2014-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多