我想允许用户创建和查看资源,但前提是:

  • 他们是员工或
  • 他们是他们试图创建/查看的对象的“所有者”

  • 我的只读权限很好用,因为当用户的主键用于生成 View 集时,他们只有获取对象列表的权限。例如:GET/api/users/1/notes 只返回 pk=1 的用户的注释。

    但是,在测试中,我发现用户可以通过将其发布到他们自己的列表端点来创建由另一个用户“拥有”的对象。例如,用户 1 可以向/api/users/1/notes 发送 POST,但将笔记数据指定为 {user: "http://host.tld/users/2/ ", text: "Look! I created a note in another person's account!"}

    我在下面找到了一个似乎工作正常的修复程序,尽管我觉得我在逆流而上。现在,在自定义权限内,我创建了一个将要创建的对象的实例,并检查其所有者是否是发出请求的用户。

    有没有更干净的方法来做到这一点?

    当前修复:
    def has_permission(self, request, view):
        if request.user.is_staff:
            return True
        elif request.method in permissions.SAFE_METHODS:
            # check that the user is looking for their own list
            return request.user == User.objects.get(pk=view.kwargs['user_pk'])
        elif request.method not in permissions.SAFE_METHODS:
            # the user can create/modify the object if the new object's user == the request user
            # roundabout way of figuring this out... probably a better way
            user_path = request.POST['user'].split(request.get_host())[1]
            func = resolve(user_path).func
            kwargs = resolve(user_path).kwargs
            user_for_object = func.cls.model.objects.get(pk=kwargs['pk'])
            return user_for_object == request.user
        else:
            return False
    

    最佳答案

    这取决于您的其余代码。

    通常,DRF 会在 check_object_permissions 或权限后端中名为 ViewSet 的方法中进行对象级检查。

    当任何泛型尝试让对象工作时, get_object 的(默认实现)调用此方法以检查权限。

    如果您只使用通用 View 集并且 /notes 是一个 @action,这将是最简单的方法。

    如果这些 ViewSet 中的对象是 note ,我会建议构建一些看起来相似的东西(例如,在你添加到 /user/ 下的每个 ViewSet 的 mixin 中)。
    有许多不同的方法来构建嵌套资源和它们的路由。

    关于python - Django Rest 框架 : Permissions based on Object Attributes/Ownership,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23974833/

    10-10 07:43