Skip to main content

电影分类接口权限设置

到现在为止,我们已经实现了很多基础功能。比如电影列表,电影详情,电影收藏等等。但是我们一直忽略了一个问题,那就是对接口的访问权限进行限制。比如说,现在任何人都可以通过操作接口,来实现对电影分类的增删改查操作。这就像任何人都可以随意进入我们家门。所以,接下里我们要对访问权限进行限制,以确保只有特定角色的用户能够执行敏感操作,比如添加、修改和删除分类。

在Django Rest Framework中,我们可以使用权限类来实现接口权限的设置。

DRF的权限类

Django REST Framework (DRF)中的 rest_framework.permissions提供了一系列的权限类,用于控制对API的访问。权限类可以全局应用,也可以应用于特定的视图或视图集。以下是DRF中一些常用的权限类:

  1. AllowAny: 允许任何用户,认证或未认证,对视图进行GET、POST等所有请求。这是最开放的权限选项。

  2. IsAuthenticated: 要求进行当前请求的用户必须通过认证。未认证的请求将被拒绝。

  3. IsAdminUser: 只允许管理员用户访问。要求用户的is_staff属性为True。

  4. IsAuthenticatedOrReadOnly: 对于认证用户,允许进行所有请求。对于未认证用户,只允许读取操作(例如GET请求)。

  5. DjangoModelPermissions: 使用Django的标准django.contrib.auth模块中的模型权限系统。这意味着它会检查用户对于模型的addchangedelete等权限。

  6. DjangoModelPermissionsOrAnonReadOnly: 类似于DjangoModelPermissions,但允许未认证用户进行读取操作。

  7. DjangoObjectPermissions: 使用Django的对象级权限系统,如django-guardian,来控制对单个对象的访问。

  8. Custom Permissions: DRF允许创建自定义权限类。你可以通过继承rest_framework.permissions.BasePermission并重写.has_permission()和/或.has_object_permission()方法来定义自己的权限逻辑。

每个权限类都可以通过视图的permission_classes属性来设置,例如:

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

class ExampleView(APIView):
permission_classes = [IsAuthenticated]

# 视图方法

或者,你可以在项目的设置文件中设置DEFAULT_PERMISSION_CLASSES来全局应用权限类:

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

使用权限类是确保你的API安全、只能被正确的用户访问的有效方式。

使用IsAdminUser的权限类

首先,我们可以使用DRF提供的IsAdminUser权限类来限制只有管理员用户可以访问分类接口的增删改操作,而其他用户可以进行查看操作。

设置IsAdminUser权限类

在我们的CategoryViewSet中,我们可以设置权限类为刚才定义的IsAdminUserOrReadOnly

dx_movie/movie/views.py
from rest_framework.permissions import IsAdminUser

class CategoryViewSet(viewsets.ModelViewSet):
queryset = Category.objects.all()
serializer_class = CategorySerializer
permission_classes = [IsAdminUser]
}

这样,我们就完成了对分类接口的权限设置。管理员用户可以执行所有操作,而其他用户只能查看分类信息。

测试IsAdminUser权限类

使用postman访问新增分类的接口,不设置Authorization参数,即用非登录账号访问,运行效果如下所示。

图57-未登录用户访问接口

设置Authorization参数,但是非管理员用户,运行效果如下所示。

图57-非管理员用户访问接口

获取管理员账号token, 如下图所示。

图57-登录管路员账号

使用管理员账号添加分类,示例如下:

图57-管理员用户添加分类

使用管理员账号删除分类,示例如下:

图57-管理员用户删除分类

warning

对于分类接口的增删改查操作,只有管理员才有权限,那么就会到值我们网站页面将无法被访问。所以,我们需要修改权限,赋予管理员增删改的权限,赋予所有用户查看的权限。

图57-管理员权限无法访问页面

自定义权限类

对于电影接口和分类接口,我们需要修改权限,赋予管理员增删改的权限,赋予所有用户查看的权限。但是DRF并没有这样的接口,不过没有关系,我们可以自定义权限类,来实现这个功能。

在dx_movie/movie/下新建一个permissions.py文件,创建一个权限类,命名permissions.py, 代码如下:

dx_movie/movie/permissions.py
from rest_framework import permissions


class IsAdminUserOrReadOnly(permissions.BasePermission):
"""
仅管理员用户可进行修改
其他用户仅可查看
"""
def has_permission(self, request, view):
# 对所有人允许 GET, HEAD, OPTIONS 请求
if request.method in permissions.SAFE_METHODS:
return True

# 仅管理员可进行其他操作
return request.user.is_superuser

permissions.SAFE_METHODS 就是'GET', 'HEAD' 和 'OPTIONS', 这些方法是任何用户都可以访问的,而其余的方法,例如'POST', 'DELETE', 'PUT'等,只有管理员用户才能访问。

接下来,在需要的视图中引入上面的权限,代码如下:

dx_movie/movie/views.py
from .permissions import IsAdminUserOrReadOnly

class MovieViewSet(viewsets.ModelViewSet):
queryset = Movie.objects.all()
serializer_class = MovieSerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_class = MovieFilter
permission_classes = [IsAdminUserOrReadOnly]

class CategoryViewSet(viewsets.ModelViewSet):
queryset = Category.objects.all()
serializer_class = CategorySerializer
permission_classes = [IsAdminUserOrReadOnly]

这样我们就配置完成了电影接口权限和分类接口权限。

此外,还可以使用DRF提供的其他权限类,比如IsAuthenticated(需要用户登录)、AllowAny(允许任何人访问)等,根据项目需求选择合适的权限类进行配置。