我的自定义权限不会阻止编辑对象的放置请求

问题描述 投票:0回答:1

我有这个权限类

class AuthorOrReadOnly(BasePermission):
    def has_object_permission(self, request, view, obj):
        if request.method in SAFE_METHODS:
            return True
        return obj.author == request.user

还有这个视图集

class PostViewSet(viewsets.ViewSet):
    permission_classes = (AuthorOrReadOnly, )
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    def list(self, request):
        serializer = self.serializer_class(self.queryset, many=True)
        return Response(serializer.data)

    def create(self, request):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            serializer.validated_data['author'] = request.user
            serializer.save()
            return Response(serializer.data, status=201)
        return Response(serializer.errors, status=400)

    def retrieve(self, request, pk=None):
        post = get_object_or_404(self.queryset, pk=pk)
        serializer = self.serializer_class(post)
        return Response(serializer.data)

    def update(self, request, pk=None):
        post = get_object_or_404(self.queryset, pk=pk)
        serializer = self.serializer_class(post, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=400)

    def partial_update(self, request, pk=None):
        post = get_object_or_404(self.queryset, pk=pk)
        serializer = self.serializer_class(post, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=400)

    def destroy(self, request, pk=None):
        post = get_object_or_404(self.queryset, pk=pk)
        post.delete()
        return Response(status=204)

当我打开视图 url 路由时,它隐藏了 put patch... 等方法的输入字段。但是当我从 shell 发出请求时,它只会编辑任何对象。所以我认为我的许可不起作用。

我已经尝试将权限放入列表和元组中,并尝试与其他权限组合,更改 has_permission 函数,但看起来它根本不起作用。

python django django-permissions
1个回答
0
投票

您检查对象权限,而不是一般权限,因此它将进入

create
/
retrieve
/
update
/等。您可以手动然后检查
.has_object_permission(…)
,但您不这样做。

您应该将权限实现为:

class AuthorOrReadOnly(BasePermission):
    # not has_object_permission
    def has_permission(self, request, view):
        if request.method in SAFE_METHODS:
            return True
        return obj.author == request.user

但是您的实现因此不会检查

.has_object_permission(…)
,这在这里并不是什么大问题,因为没有必要进行检查,但如果以后混合其他权限,可能会出现安全漏洞。

您可以使用

ModelViewSet
 [drf-doc],它在此处实现了所有样板逻辑:

class PostViewSet(viewsets.ModelViewSet):
    permission_classes = (AuthorOrReadOnly,)
    queryset = Post.objects.all()
    serializer_class = PostSerializer

    # no list()
    # no create()
    def perform_create(self, serializer):
        serializer.validated_data['author'] = request.user
        super().perform_create(serializer)

    # no retrieve()
    # no update()~
    # no partial_update()
    # no destroy()
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.