• 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
  • 相关阅读:
    在庫購買管理(MM)
    指図ステータス
    購買発注変更、照会画面に初期表示される発注伝票はどのように決まっているのか
    金額処理
    翻訳
    mysql 与mongodb的特点与优劣
    PHP经典算法
    Linux下PHP安装redis扩展
    Linux上安装Redis教程
    PHP插入法排序
  • 原文地址:https://www.cnblogs.com/ctztake/p/8422787.html
Copyright © 2020-2023  润新知