DRF - 权限

权限组件


  • 权限校验和认证校验必须同时使用,并且权限校验是排在认证校验之后的,在源码中可以查找到其执行顺序

  • 权限校验也很重要,认证校验可以确保一个用户登录之后才能对接口做操作,而权限校验可以依据这个登录用户的类型来想定对接口做哪些操作

1.自定权限的使用步骤

(1)编写一个权限类,继承【权限模块】中的BasePermission

from rest_framework.permissions import BasePermission

(2)重写has_permission方法,在源码中发现该方法需要两个参数request和view,来进行权限认证

(3)如果用户拥有权限返回True

image-20230207190624522

(4)如果用户没有权限,则向对象中放一个属性message来返回错误信息

# 如果表模型中,使用了choice就可以通过get_字段名_display() 拿到choice对应的信息
self.message = '你是【%s】,你没有权限' % request.user.get_user_type_display()

2.全局使用与局部使用

全局、局部、默认配置的优先级

1.局部(视图类中)

2.全局(settings.py中)

3.默认(默认配置文件中)

权限类可以设置是全局使用或者是局部使用。

并且权限类可以配置多个,按照从前向后到顺序执行,如果前面有返回值,权限就不继续往下执行了

(1)局部权限:对单独的视图类生效

在视图类中,通过authentication_classes来进行限制认证

class BookDetailView(ViewSetMixin, RetrieveAPIView):
    """查询单个"""
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    "局部认证"
    authentication_classes = [LoginAuth]

(2)全局权限:对于全局的视图类生效

settings.py在配置文件中配置

REST_FRAMEWORK = {
    # 【认证】的全局配置
    'DEFAULT_AUTHENTICATION_CLASSES':'app01.authenticate.LoginAuth',
}

(3)全局权限 + 局部禁用

在全局的基础上,进行局部视图类的权限校验禁用

class BookDetailView(ViewSetMixin, RetrieveAPIView):
    # 列表为空,则为局部禁用
    permission_classes = [] 

3.代码演示

permission.py - 定制的权限类

继承BasePermission,然后重写has_permission方法实现权限校验

# 写权限类,继承BasePermission,然后重写has_permission方法,在方法中实现权限
from rest_framework.permissions import BasePermission


class CommonPermission(BasePermission):

    # 源码中发现has_permission 需要两个参数request和view
    def has_permission(self, request, view):
        # 1。判断权限,则是判断登录用户的user_type是什么,超级用户才可以返回true
        if request.user.user_type == 1:
            return True
        else:
            # 2.如果没有权限,则向对象中放一个属性message来返回错误信息
            # 如果表模型中,使用了choice就可以通过get_字段名_display() 拿到choice对应的信息
            self.message = '你是【%s】,你没有权限' % request.user.get_user_type_display()
            return False

models.py - 模型层

模型层的用户表需要有用户的权限类别,在进行权限校验的时候进行判断

class User(models.Model):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=32)
    # 用于用户权限校验的字段
    user_type = models.IntegerField(choices=((1, '超级管理员'), (2, '普通用户'), (3, '黑用户')), default=2)


class UserToken(models.Model):
    token = models.CharField(max_length=32)
    user = models.OneToOneField(to='User', on_delete=models.CASCADE, null=True)

views.py - 视图类

在视图类中,无论全局还是局部,都需要进行了登录认证校验,才能进行权限校验

# 导入认证类
from .authenticate import LoginAuth
# 导入权限类
from .permission import CommonPermission

class BookView(ViewSetMixin, ListAPIView):
    """查询所有"""
    queryset = Book.objects.all()
    serializer_class = BookSerializer


class BookDetailView(ViewSetMixin, RetrieveAPIView):
    """查询单个"""
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    "局部登录认证"
    # authentication_classes = [LoginAuth]
    "登录后,局部权限校验,校验权限之前必须进行了认证"
    permission_classes = [CommonPermission]

在权限类继承类的源码中可以看到先校验了认证,才开始校验权限

image-20230207192608442

posted @ 2023-02-07 19:35  Duosg  阅读(84)  评论(0编辑  收藏  举报