Python Django-如何防止访问其他用户';物体?

Python Django-如何防止访问其他用户';物体?,python,django,python-3.x,django-rest-framework,django-views,Python,Django,Python 3.x,Django Rest Framework,Django Views,让我们假设我有这样的URLusers/{id}/objects,并且我被认证为id等于1的用户。目前,我可以访问ID为2、3等的用户对象。有人知道如何防止这种情况发生吗 class UserObject(GenericAPIView): permission_classes = [UserPermission] def get(self, request, user_id): try: object = Object.o

让我们假设我有这样的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)

您可以使用
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
注意:我建议使用第一个选项

注意:此代码是一个示例,如果它不能立即工作,请尝试
理解并适应这个想法。我没有测试它,它可能需要一些AJUST,特别是获取
user\u id
frorm
响应的部分。path

如果您重载视图的
get\u queryset
以仅返回属于当前用户的对象,那么Django将自行处理相应的错误和响应。比如说,

class MyView(GenericAPIView):

    serializer_class = serializers.MySerializer
    permission_classes = (IsAuthenticated,)

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

另请参见模板中的

检查视图中的id==request.user.id,而不是。@mohammedqudah我用if
user\u id==self.request.user.id:
尝试了它,但它不起作用。也许可以在
GetPermission
Class?@VincentBuscarello中检查它不,只有所有者可以访问这些对象。目前,它只需要是一个用户并经过身份验证,您可以访问不同用户的所有对象。我想使它能够只访问自己的对象。@VincentBuscarello我在下面添加了
print(“test”)
def has_permission(self,request,view):
并且在发送
users/1/对象之后,会打印
test
,但也许可以将其添加到UserPermission类中?如果我使用你的解决方案,我将有很多常规视图需要修改。我认为你可以做到,尽管这有点棘手。您需要从自定义权限类中的
has\u permission
函数访问
user\u id
。由于
请求
对象是
HttpRequest
的一个属性,它是一个
路径
字段,您可以从那里提取
用户id
,并将其与
请求.user.id
进行比较,使其在不接触视图的情况下工作。您可以告诉我如何在
类用户权限上执行此操作吗?编辑答案即可。只需将1更改为2它不起作用。我将代码添加到更新的问题中。也许我做错了什么?可能是因为很多原因,比如你没有正确的身份验证类。或者
所有者
不是
组合
s链接到
用户
s的方式。“所有者”一词没有什么神奇之处——您必须更改示例过滤器以适应您自己的关系情况。此外,如果您是这样做的,您可能不需要重载
get
——关键是您可以通过这一点实现您的目标,而不需要为每个视图重载
get