Django - 如何防止访问其他用户的对象?

时间:2017-11-14 18:40:23

标签: python django python-3.x django-rest-framework django-views

我们假设我有这样的URL users/{id}/objects并且我被认证为ID等于1的用户。目前我可以访问ID等于2,3等的用户的对象。有没有人知道如何我可以阻止这个吗?

class UserObject(GenericAPIView):

    permission_classes = [UserPermission]
    def get(self, request, user_id):

            try:
                object = Object.objects.filter(user=user_id)
            except Object.DoesNotExist:
                return Response(status=status.HTTP_404_NOT_FOUND)
            serializer = ObjectSerializer(object, many=True)
            return Response(serializer.data)


class UserPermission(permissions.BasePermission):

    def has_permission(self, request, view):
        if request.user and request.user.is_authenticated():
            return True
        return False

我试过这样的方式:

serializer_class = ObjectSerializer
permission_classes = [IsAuthenticated, ]

def get_queryset(self):
    return Object.objects.filter(owner=self.request.user)

def get(self, request, user_id):

        try:
            object = Object.objects.filter(user=user_id)
        except Object.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        serializer = ObjectSerializer(object, many=True)
        return Response(serializer.data)

2 个答案:

答案 0 :(得分:2)

如果重载视图的get_queryset只返回属于当前用户的对象,那么Django将自己处理相应的错误和响应。例如,

class MyView(GenericAPIView):

    serializer_class = serializers.MySerializer
    permission_classes = (IsAuthenticated,)

    def get_queryset(self):
        return MyModel.objects.filter(owner=self.request.user)

另见http://www.django-rest-framework.org/api-guide/generic-views/#attributes

答案 1 :(得分:1)

您只能使用IsAuthenticated权限来检查是否有人登录,如果用户要求提供自己的数据,则可以“手动”检查。像这样:

class UserObject(GenericAPIView):

    permission_classes = (IsAuthenticated,)
    def get(self, request, user_id):

        if (str(reques.user.id) != user_id):
            return Response(status=status.HTTP_403_FORBIDDEN)

        try:
            object = Object.objects.filter(user=user_id)
        except Object.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        serializer = ObjectSerializer(object, many=True)
        return Response(serializer.data)

如果你真的想使用自定义权限,你可以不受影响地使用,并且允许你这样的许可:

class UserPermission(permissions.BasePermission):

    def has_permission(self, request, view):
        if (not request.user.is_authenticated()):
            return False

        user_id = request.path.split('/')[1]

        if (str(request.user.id) == user_id):
            return True

        return False

注意:我建议使用第一个选项。

注意:此代码是一个示例,如果它不能立即工作,请尝试 理解这个想法并进行调整。我没有测试它,它可能需要一些调整,特别是获得user_id frorm response.path的部分。