DRF - 权限
目录
权限组件
-
权限校验和认证校验必须同时使用,并且权限校验是排在认证校验之后的,在源码中可以查找到其执行顺序
-
权限校验也很重要,认证校验可以确保一个用户登录之后才能对接口做操作,而权限校验可以依据这个登录用户的类型来想定对接口做哪些操作
1.自定权限的使用步骤
(1)编写一个权限类,继承【权限模块】中的BasePermission
from rest_framework.permissions import BasePermission
(2)重写has_permission
方法,在源码中发现该方法需要两个参数request和view,来进行权限认证
(3)如果用户拥有权限返回True
(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]
在权限类继承类的源码中可以看到先校验了认证,才开始校验权限