跳转至

DRF权限

在 Django REST Framework (DRF) 中,权限是一个非常重要的概念,它决定了哪些用户可以访问哪些视图。DRF 提供了多种内置的权限类,并允许开发者自定义权限,以满足特定的需求。以下是详细介绍 DRF 中权限的内容:

内置权限类

DRF 提供了一些常用的内置权限类,包含在 rest_framework.permissions 模块中。

AllowAny

  • 允许任何人访问,无需进行身份验证。
from rest_framework.permissions import AllowAny

class MyView(APIView):
    permission_classes = [AllowAny]
    # ...

IsAuthenticated

  • 仅允许经过身份验证的用户访问。
from rest_framework.permissions import IsAuthenticated

class MyView(APIView):
    permission_classes = [IsAuthenticated]
    # ...

IsAdminUser

  • 仅允许管理员用户访问(is_staff 属性为 True)。
from rest_framework.permissions import IsAdminUser

class MyView(APIView):
    permission_classes = [IsAdminUser]
    # ...

IsAuthenticatedOrReadOnly

  • 对于未经身份验证的用户,允许只读操作;对经过身份验证的用户,允许读写操作。
from rest_framework.permissions import IsAuthenticatedOrReadOnly

class MyView(APIView):
    permission_classes = [IsAuthenticatedOrReadOnly]
    # ...

自定义权限类

有时内置的权限类不能满足需求,这时可以创建自定义权限类。自定义权限类需要继承 BasePermission 并重写 has_permission 和/或 has_object_permission 方法。

  • has_permission(self, request, view):用于检查用户是否对视图有权限。
  • has_object_permission(self, request, view, obj):用于检查用户是否对特定对象有权限。

示例:仅允许作者修改自己的对象

from rest_framework.permissions import BasePermission

class IsOwner(BasePermission):
    def has_object_permission(self, request, view, obj):
        # 假设对象有一个 `owner` 属性
        return obj.owner == request.user

使用自定义权限类

class MyView(APIView):
    permission_classes = [IsAuthenticated, IsOwner]

    def get(self, request, *args, **kwargs):
        # 获取对象实例
        obj = self.get_object()
        self.check_object_permissions(request, obj)
        # ...

在视图中使用权限

权限类可以在视图或视图集的 permission_classes 属性中指定。

APIView 中使用权限

from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated

class MyView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, *args, **kwargs):
        # 处理 GET 请求
        return Response(data)

ViewSet 中使用权限

from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAuthenticated

class MyViewSet(ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer
    permission_classes = [IsAuthenticated]

全局权限设置

你可以在 DRF 的配置文件中设置全局权限,所有视图默认都会使用这些权限。

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}

结合多个权限类

你可以在视图中组合多个权限类,所有的权限类都必须通过检查才能授予访问权限。

from rest_framework.permissions import IsAuthenticated, IsAdminUser

class MyView(APIView):
    permission_classes = [IsAuthenticated, IsAdminUser]

    def get(self, request, *args, **kwargs):
        # 处理 GET 请求
        return Response(data)

示例:基于权限的简单 API

创建权限类

# permissions.py
from rest_framework.permissions import BasePermission

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

使用权限类

# views.py
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from .permissions import IsOwnerOrReadOnly
from .models import MyModel
from .serializers import MyModelSerializer

class MyModelDetail(APIView):
    permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]

    def get_object(self, pk):
        try:
            return MyModel.objects.get(pk=pk)
        except MyModel.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        mymodel = self.get_object(pk)
        self.check_object_permissions(request, mymodel)
        serializer = MyModelSerializer(mymodel)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        mymodel = self.get_object(pk)
        self.check_object_permissions(request, mymodel)
        serializer = MyModelSerializer(mymodel, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

总结

在 Django REST Framework 中,权限管理是确保 API 安全性的重要组成部分。DRF 提供了多种内置权限类,并支持自定义权限类,以满足不同的安全需求。通过合理配置权限,可以有效控制用户对视图和对象的访问权限,保护数据安全。

评论