【问题标题】:Django rest framework : Prevent one user from deleting/Editing/Viewing other users in ModelViewSetDjango rest框架:防止一个用户删除/编辑/查看ModelViewSet中的其他用户
【发布时间】:2021-12-08 11:03:05
【问题描述】:

我在我的 Django REST 框架中使用 Django 用户模型。为此,我将 Django 的 ModelViewSet 用于我的 User 类。

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

Serializers.py

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'password']

        extra_kwargs = {
            'password' : {
                'write_only':True,
                'required': True
            }
        }
    
    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        Token.objects.create(user=user) # create token for the user
        return user

但目前来自邮递员,当我使用一个用户的令牌发出请求以查看、删除、编辑其他用户时

http://127.0.0.1:8000/api/users/4/

它能够编辑/删除/查看其他用户。我不希望这种情况发生,一个用户只能对自己提出请求,这就是我想要的。

这是我的应用程序 urls.py

urls.py

from django.urls import path, include
from .views import ArticleViewSet, UserViewSet
from rest_framework.routers import DefaultRouter


router = DefaultRouter()
router.register('articles', ArticleViewSet, basename='articles')
router.register('users', UserViewSet, basename = 'users')


urlpatterns = [
    path('api/', include(router.urls)), 
]

如何防止一个用户在发出 GET/POST/PUT/DELETE 请求时访问其他用户。

编辑 1: 添加 IsOwnerOfObject 类后,他在下面的回答中提供,现在当我请求用户本人的详细信息时,我得到了

未提供身份验证凭据。

【问题讨论】:

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


    【解决方案1】:

    创建一个名为permissions.py的文件。

    from rest_framework import permissions
    
    
    class IsOwnerOfObject(permissions.BasePermission):
        def has_object_permission(self, request, view, obj):
    
            return obj == request.user
    

    接下来将权限类添加到您的 ModelViewSet:

    from yourapp.permissions import IsOwnerOfObject
    
    class UserViewSet(viewsets.ModelViewSet):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    
        permission_classes = [IsOwnerOfObject, <other permission classes you want to use>]
    

    更多信息在这里: https://www.django-rest-framework.org/tutorial/4-authentication-and-permissions/#object-level-permissions

    【讨论】:

    • 我相信obj.owner 如果他在 User 上没有该字段,则会出错。对于这个特定的模型,他可以做return obj == request.user
    • 是的,我的错误,复制粘贴错误。
    • 尝试了解决方案,但现在我在发出 GET 请求时收到了Authentication credentials were not provided.。在上面的问题中检查我的编辑
    • 发现,更新。我想我们需要再次提供 authentication_classes
    【解决方案2】:

    如果你想完全禁用删除(这可能是正确的,因为如果你想“删除”一个用户,你应该停用它。)然后你可以用这个替换你的视图:

    from rest_framework import viewsets
    from rest_framework import generics
    
    class UserViewSet(
        generics.CreateModelMixin,
        generics.ListModelMixin,
        generics.RetrieveModelMixin,
        generics.UpdateModelMixin,
        generics.viewsets.GenericViewSet
    ):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    

    然后您可以使用 Ene Paul 的回答来限制可以编辑的人。

    【讨论】:

    • 试过 Ene 的回答我在发出 GET 请求时收到Authentication credentials were not provided.。在上面的问题中检查我的编辑
    • 发现,更新
    【解决方案3】:

    根据 Ene 的回答构建,需要提供身份验证和权限类。

    创建一个名为 permissions.py 的文件。

    from rest_framework import permissions
    
    class IsOwnerOfObject(permissions.BasePermission):
        def has_object_permission(self, request, view, obj):
            return obj == request.user
    

    接下来给ModelViewSet添加权限和认证类:

    from api.permissions import IsOwnerOfObject
    from rest_framework.authentication import TokenAuthentication
    from rest_framework.permissions import IsAuthenticated
    
    class UserViewSet(viewsets.ModelViewSet):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    
        permission_classes = [IsAuthenticated, IsOwnerOfObject]
        authentication_classes = (TokenAuthentication,)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多