• Django rest framework 权限操作(源码分析)


    这一篇是基于上一篇写的,上一篇谢了认证的具体流程,看懂了上一篇这一篇才能看懂,

    当用户访问是 首先执行dispatch函数,当执行当第二部时:

       #2.处理版本信息 处理认证信息 处理权限信息 对用户的访问频率进行限制
                self.initial(request, *args, **kwargs)

    进入到initial方法:

    def initial(self, request, *args, **kwargs):
            """
            Runs anything that needs to occur prior to calling the method handler.
            """
            self.format_kwarg = self.get_format_suffix(**kwargs)
    
            # Perform content negotiation and store the accepted info on the request
            neg = self.perform_content_negotiation(request)
            request.accepted_renderer, request.accepted_media_type = neg
    
            # Determine the API version, if versioning is in use.
            #2.1处理版本信息
            version, scheme = self.determine_version(request, *args, **kwargs)
            request.version, request.versioning_scheme = version, scheme
    
            # Ensure that the incoming request is permitted
            #2.2处理认证信息
            self.perform_authentication(request)
            #2.3处理权限信息
            self.check_permissions(request)
            #2.4对用户的访问频率进行限制
            self.check_throttles(request)
    #2.3处理权限信息
            self.check_permissions(request)

    下面 开始 权限的具体分析:

    进入到check_permissions函数中

    #检查权限
        def check_permissions(self, request):
            """
            Check if the request should be permitted.
            Raises an appropriate exception if the request is not permitted.
            """
            #elf.get_permissions()得到的是一个权限对象列表
            for permission in self.get_permissions():
                #在自定义的Permission中has_permission方法是必须要有的
                #判断当前has_permission返回的是True,False,还是抛出异常
                #如果是True则表示权限通过,False执行下面代码
                if not permission.has_permission(request, self):
                    #为False的话则抛出异常,当然这个异常返回的提示信息是英文的,如果我们想让他显示我们自定义的提示信息
                    #我们重写permission_denied方法即可
                    self.permission_denied(
                        #从自定义的Permission类中获取message(权限错误提示信息),一般自定义的话都建议写上,如果没有则为默认的(英文提示)
                        request, message=getattr(permission, 'message', None)
                    )

    查看permission_denied方法(如果has_permission返回True则不执行该方法)

    def permission_denied(self, request, message=None):
            """
            If request is not permitted, determine what kind of exception to raise.
            """
            if request.authenticators and not request.successful_authenticator:
                #没有登录提示的错误信息
                raise exceptions.NotAuthenticated()
            #一般是登陆了但是没有权限提示
            raise exceptions.PermissionDenied(detail=message)

    举例:

    from django.db import models
    
    # Create your models here.
    class Userinfo(models.Model):
        name=models.CharField(max_length=32,verbose_name='用户名')
        pwd=models.CharField(max_length=32,verbose_name='密码')
        token=models.CharField(max_length=64,null=True)
    
        def __str__(self):
            return self.name
    
    models
    urlpatterns = [
        url(r'^p/', app02_views.Pview.as_view()),
        url(r'^mp/', app02_views.Aview.as_view()),
        url(r'^jp/', app02_views.Jview.as_view()),
    ]
    from django.shortcuts import render
    from rest_framework.views import APIView
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.permissions import BasePermission
    from rest_framework.response import Response
    from rest_framework import exceptions
    
    
    from app01 import models
    # Create your views here.
    
    class MyAuthentication(BaseAuthentication):
    
        def authenticate(self, request):
            token=request.query_params.get('token')
            user=models.Userinfo.objects.filter(token=token).first()
            if user:
                return (user.name,user)
            return None
    
    class MyPermission(object):
        message = '登录才可以访问'
        def has_permission(self,request, view):
            if request.user:
                return True
            return False
    
    class AdminPermission(object):
        message = '会员才可以访问'
        def has_permission(self,request,view):
            if request.user=='ctz':
                return True
            return False
    
    class Pview(APIView):
        '''
        所有人都可以看
        '''
        authentication_classes = [MyAuthentication,]
        permission_classes = []
        def get(self,request):
            return Response('图片列表')
        def post(self,request):
            pass
    
    
    
    
    class Aview(APIView):
        '''
        登录的人可以看
        '''
        authentication_classes = [MyAuthentication,]
        permission_classes = [MyPermission,]
        def get(self,request):
            return Response('美国电影列表')
        def post(self,request):
            pass
    
        def permission_denied(self, request, message=None):
            """
            If request is not permitted, determine what kind of exception to raise.
            """
    
            if request.authenticators and not request.successful_authenticator:
                raise exceptions.NotAuthenticated('无权访问')
            raise exceptions.PermissionDenied(detail=message)
    
    class Jview(APIView):
        '''
        会员才可以看
        '''
        authentication_classes = [MyAuthentication,]
        permission_classes = [MyPermission,AdminPermission,]
        def get(self,request):
            return Response('日本电影列表')
        def post(self,request):
            pass
    
        def permission_denied(self, request, message=None):
            """
            If request is not permitted, determine what kind of exception to raise.
            """
    
            if request.authenticators and not request.successful_authenticator:
                raise exceptions.NotAuthenticated('无权访问')
            raise exceptions.PermissionDenied(detail=message)
    
    Views

    上面的是局部的只能在当前类中可以用,如果想在全局中用:只需要在settings中配置即可:

    from django.shortcuts import render
    from rest_framework.views import APIView
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.permissions import BasePermission
    from rest_framework.response import Response
    from rest_framework import exceptions
    
    from app02.utils import MyPermission
    #
    #
    from app01 import models
    # # Create your views here.
    #
    # class MyAuthentication(BaseAuthentication):
    #
    #     def authenticate(self, request):
    #         token=request.query_params.get('token')
    #         user=models.Userinfo.objects.filter(token=token).first()
    #         if user:
    #             return (user.name,user)
    #         return None
    #
    # class MyPermission(object):
    #     message = '登录才可以访问'
    #     def has_permission(self,request, view):
    #         if request.user:
    #             return True
    #         return False
    #
    # class AdminPermission(object):
    #     message = '会员才可以访问'
    #     def has_permission(self,request,view):
    #         if request.user=='ctz':
    #             return True
    #         return False
    
    class Pview(APIView):
        '''
        所有人都可以看
        '''
    
        permission_classes = []
        def get(self,request):
            return Response('图片列表')
        def post(self,request):
            pass
    
    
    
    
    class Aview(APIView):
        '''
        登录的人可以看
        '''
      #  authentication_classes = [MyAuthentication,]
        permission_classes = [MyPermission,]
        def get(self,request):
            return Response('美国电影列表')
        def post(self,request):
            pass
    
        def permission_denied(self, request, message=None):
            """
            If request is not permitted, determine what kind of exception to raise.
            """
    
            if request.authenticators and not request.successful_authenticator:
                raise exceptions.NotAuthenticated('无权访问')
            raise exceptions.PermissionDenied(detail=message)
    
    class Jview(APIView):
        '''
        会员才可以看
        '''
        # authentication_classes = [MyAuthentication,]
        # permission_classes = [MyPermission,AdminPermission,]
        def get(self,request):
            return Response('日本电影列表')
        def post(self,request):
            pass
    
        def permission_denied(self, request, message=None):
            """
            If request is not permitted, determine what kind of exception to raise.
            """
    
            if request.authenticators and not request.successful_authenticator:
                raise exceptions.NotAuthenticated('无权访问')
            raise exceptions.PermissionDenied(detail=message)
    
    Views
    from django.shortcuts import render
    
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.permissions import BasePermission
    from rest_framework.response import Response
    from rest_framework import exceptions
    from rest_framework.exceptions import APIException
    
    
    from app01 import models
    # Create your views here.
    
    class MyAuthentication(BaseAuthentication):
    
        def authenticate(self, request):
            token=request.query_params.get('token')
            user=models.Userinfo.objects.filter(token=token).first()
            if user:
                return (user.name,user)
            return None
    
    class MyPermission(object):
        message = '登录才可以访问'
        def has_permission(self,request, view):
            if request.user:
                return True
            return False
    
    class AdminPermission(object):
        message = '会员才可以访问'
        def has_permission(self,request,view):
            if request.user=='ctz':
                return True
            return False
    
    utils
    REST_FRAMEWORK = {
        'UNAUTHENTICATED_USER': None,
        'UNAUTHENTICATED_TOKEN': None,
        "DEFAULT_AUTHENTICATION_CLASSES": [
          # "app01.utils.MyAuthentication",
            "app02.utils.MyAuthentication",
        ],
        "DEFAULT_PERMISSION_CLASSES":[
           "app02.utils.MyPermission",
           "app02.utils.AdminPermission",
        ],
    }
    
    settings
  • 相关阅读:
    Kafka简介
    Storm之详解spout、blot
    【刷题】面筋-页面很卡的原因分析及解决方案
    【JAVA】栈和堆,JVM内存概述
    【刷题】面筋-游戏测试-农药测试向分析
    【刷题】面筋-游戏测试-什么样的游戏可以称为一个好的游戏
    【刷题】面筋-两颗鸡蛋测临界楼层的问题
    【刷题】面筋-游戏测试的目的和流程
    【刷题】面筋-测开-游戏测试用例要点与测试俄罗斯方块
    【刷题】面筋-游戏平衡性
  • 原文地址:https://www.cnblogs.com/sunxiuwen/p/9979478.html
Copyright © 2020-2023  润新知