五、Drf权限组件

五、权限组件

权限组件=[权限类,权限类,权限类…]

执行所有权限类的has_permission方法,通过返回True,不通过返回False

默认情况下,所有的权限类都通过,才返回True

5.1简单应用权限组件

#ext.per
class MyPermission1(BasePermission):

    def has_permission(self, request, view):
        """
            Return `True` if permission is granted, `False` otherwise.
        """
        token1=request.query_params.get('token1',None)
        
        if token1=='111':
            #如果token1==111,则代表有权限,返回True
            return True
        #否则返回False
        return False
#views视图类
class OrderView(APIView):  
    # 调用权限组件
    permission_classes = [ext.per.MyPermission1,]
    def get(self, request):

        return Response('order')

效果1:token1正确,有权限访问

在这里插入图片描述

效果2:token2错误,无权限访问

在这里插入图片描述

5.2自定义错误信息

class MyPermission1(BasePermission):
    #自定义错误信息
    message={'code':2001,'errMsg':'无权限访问该视图'}
    def has_permission(self, request, view):

        token1=request.query_params.get('token1',None)
      
        if token1=='111':
            return True
        return False

效果:

在这里插入图片描述

5.3多个权限类

只有所有权限类都返回True,才能获取访问权限。任何一个类返回False,则不会执行该类后面的权限类。

from rest_framework.permissions import BasePermission
class MyPermission1(BasePermission):
    #权限类1
    message={'code':2001,'errMsg':'token1验证失败,无权访问'}
    def has_permission(self, request, view):
        """
            Return `True` if permission is granted, `False` otherwise.
        """
        token1=request.query_params.get('token1',None)        
        if token1=='111':
            return True
        return False

class MyPermission2(BasePermission):
    #权限类2
    message={'code':2001,'errMsg':'token2验证失败,无权访问'}
    def has_permission(self, request, view):
        """
            Return `True` if permission is granted, `False` otherwise.
        """
        token2=request.query_params.get('token2',None)        
        if token2=='222':
            return True
        return False

#视图类
class OrderView(APIView):
    # 不需要认证
    authentication_classes = []
    # 调用多个权限组件
    permission_classes = [ext.per.MyPermission1,ext.per.MyPermission2,]
    def get(self, request):

        return Response('order')

效果1(两个token都正确):

在这里插入图片描述

效果2(一个token正常,一个token错误)

在这里插入图片描述

5.4权限类的全局配置

#settings.py
REST_FRAMEWORK = {
    "UNAUTHENTICATED_USER": None,    
    #权限类的全局配置,这里配置以后,所有的视图都需要进行权限认证。
    'DEFAULT_PERMISSION_CLASSES':["ext.per.MyPermission1","ext.per.MyPermission2",],
}

5.5权限组件扩展

(重写check_permissions方法,让视图只要满足一个权限类,就能访问)

class OrderView(APIView):
    # 不需要认证
    authentication_classes = []

    def check_permissions(self, request):
        #重写check_permissions方法
        no_permission=[]
        for permission in self.get_permissions():            
            if permission.has_permission(request, self):
                #只要有一个权限类满足,就正常返回
                return
            #如果有不满足的权限类,则将它加入列表
            no_permission.append(permission)
        #如果有不满足的权限类,则拒绝访问,并抛出错误信息
        self.permission_denied(
            request,
            message=getattr(no_permission[0], 'message', None),
            code=getattr(no_permission[0], 'code', None)
        )
    def get(self, request):

        return Response('order')

(重写APIView方法,视图继承该类,让视图只要满足一个权限类,就能访问)

#ext.myapiview
class MyAPIView(APIView):
    #重写APIView中的check_permissions方法,视图继承该类,让视图只要满足一个权限类,就能访问
    def check_permissions(self, request):
        #创建一个空列表,用于存入未通过认证的权限类
        no_permission = []     
        if not self.get_permissions():
            #如果权限类列表为空,表示无需认证权限,正常返回
            return 
        for permission in self.get_permissions():
            #遍历视图权限组中所中引用的所有权限类
            if permission.has_permission(request, self):
                #如果权限认证通过,则正常返回
                return
            #将未通过权限认证的权限类存入列表
            no_permission.append(permission)
        self.permission_denied(
            #拒绝访问,并获取错误信息
            request,
            message=getattr(no_permission[-1], 'message', None),
            code=getattr(no_permission[-1], 'code', None)
        )
#视图类继承上面重写过的APIView类
class OrderView(MyAPIView):
    # 不需要认证
    authentication_classes = []


    def get(self, request):

        return Response('order')

5.6权限组件实例:

三个视图,login,user,order

login:用户登入,无需认证,也无需任何权限即可访问

user:用户信息,需要认证,需要管理员权限或主管权限或员工权限才能访问

order:订单信息,需要认证,需要管理员权限或主管权限才能访问

表结构:

class User(models.Model):
    name=models.CharField(verbose_name='name',max_length=64)
    password=models.CharField(verbose_name='password',max_length=64)
    token=models.CharField(verbose_name='token',max_length=64,null=True,blank=True)
    ROLE_CHOICES=(
        (1,'管理员'),
        (2,'部门主管'),
        (3,'员工')
                 )
    role=models.SmallIntegerField(verbose_name='角色',choices=ROLE_CHOICES,default=3)

重写APIView方法,视图继承该类,让视图只要满足一个权限类,就能访问

from rest_framework.views import APIView
class MyAPIView(APIView):
    #重写APIView中的check_permissions方法,视图继承该类,让视图只要满足一个权限类,就能访问
    def check_permissions(self, request):
        #创建一个空列表,用于存入未通过认证的权限类
        no_permission = []        
        for permission in self.get_permissions():
            #遍历视图权限组中所中引用的所有权限类
            if permission.has_permission(request, self):
                #如果权限认证通过,则正常返回
                return
            #将未通过权限认证的权限类存入列表
            no_permission.append(permission)
        self.permission_denied(
            #拒绝访问,并获取错误信息
            request,
            message=getattr(no_permission[-1], 'message', None),
            code=getattr(no_permission[-1], 'code', None)
        )

编写权限类

#ext.per
rom rest_framework.permissions import BasePermission
from app_api import models

class AdminPermission(BasePermission):
    #管理员权限验证
    message={'code':2001,'errMsg':'您不是管理员,无权访问'}
    def has_permission(self, request, view):
        """
            Return `True` if permission is granted, `False` otherwise.
        """
        token=request.query_params.get('token',None)

        if not token:
            return False
        user_obj=models.User.objects.filter(token=token).first()
        if not user_obj:
            return False
        if user_obj.role==1:
            #判断当前用户是否为管理员
            return True
        return False

class ManagePermission(BasePermission):
    # 部门主管权限验证
    message={'code':2001,'errMsg':'您不是部门主管,无权访问'}
    def has_permission(self, request, view):
        """
            Return `True` if permission is granted, `False` otherwise.
        """
        token=request.query_params.get('token',None)
        if not token:
            return False
        user_obj=models.User.objects.filter(token=token).first()
        if not user_obj:
            return False
        if user_obj.role==2:
            #判断当前用户是否为部门主管
            return True
        return False


class UserPermission(BasePermission):
    # 员工权限验证
    message={'code':2001,'errMsg':'您不是员工员,无权访问'}
    def has_permission(self, request, view):
        """
            Return `True` if permission is granted, `False` otherwise.
        """
        token=request.query_params.get('token',None)
        if not token:
            return False
        user_obj=models.User.objects.filter(token=token).first()
        if not user_obj:
            return False
        if user_obj.role==3:
            #判断当前用户是否为员工
            return True
        return False

视图类

class LoginView(MyAPIView):
    #用户登入,不需要认证,不需要任何权限
    authentication_classes = []
    permission_classes=[]
    def post(self,request):
        name=request.data.get('name')
        password=request.data.get('password')
        print(name,password)
        user_obj=models.User.objects.filter(name=name,password=password).first()
        if not user_obj:
            #用户名密码错误
            return Response({'status':False,'errMsg':'用户名或密码错误'})
        token=str(uuid.uuid4())
        user_obj.token=token
        user_obj.save()


        return Response({'status':True,'token':token})


class UserView(MyAPIView):
    #查看用户信息
    #需要认证,需要管理员权限或主管权限或员工权限
    permission_classes=[AdminPermission,ManagePermission,UserPermission,]
    def get(self, request):
        user_info=models.User.objects.all().values('name','token')
        return Response(user_info)

class OrderView(MyAPIView):
    # 需要认证
    # 需要管理员权限或主管权限
    permission_classes = [AdminPermission, ManagePermission,]
    def get(self, request):

        return Response('order')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暮毅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值