zoukankan      html  css  js  c++  java
  • Django rest framework 权限操作(源码分析)

    知识回顾http://www.cnblogs.com/ctztake/p/8419059.html  

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

    当用户访问是 首先执行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()),
    ]
    urls
    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
  • 相关阅读:
    北京燃气IC卡充值笔记
    随机分析、随机控制等科目在量化投资、计算金融方向有哪些应用?
    量化交易平台大全
    Doctor of Philosophy in Computational and Mathematical Engineering
    Institute for Computational and Mathematical Engineering
    Requirements for the Master of Science in Computational and Mathematical Engineering
    MSc in Mathematical and Computational Finance
    万字长文:详解多智能体强化学习的基础和应用
    数据处理思想和程序架构: 使用Mbedtls包中的SSL,和服务器进行网络加密通信
    31-STM32+W5500+AIR202/302基本控制篇-功能优化-W5500移植mbedtls库以SSL方式连接MQTT服务器(单向忽略认证)
  • 原文地址:https://www.cnblogs.com/ctztake/p/8422787.html
Copyright © 2011-2022 走看看