Django rest框架:防止一个用户删除/编辑/查看ModelViewSet中的其他用户

Posted

技术标签:

【中文标题】Django rest框架:防止一个用户删除/编辑/查看ModelViewSet中的其他用户【英文标题】:Django rest framework : Prevent one user from deleting/Editing/Viewing other users in 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 类后,他在下面的回答中提供,现在当我请求用户本人的详细信息时,我得到了

未提供身份验证凭据。

【问题讨论】:

【参考方案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,)

【讨论】:

以上是关于Django rest框架:防止一个用户删除/编辑/查看ModelViewSet中的其他用户的主要内容,如果未能解决你的问题,请参考以下文章

如何:创建一个视图和序列化器,用于添加,编辑和删除具有外部关系的对象django rest framework

Django rest框架将POST数据分配给特定用户

用于 Django REST 框架的通用 ModelSerializer

Django rest 框架 jwt 令牌权限

django rest framework API 编辑功能

在 django rest 框架中删除多个对象