zoukankan      html  css  js  c++  java
  • drf源码分析系列---权限

    权限的使用

    全局使用

    from rest_framework.permissions import BasePermission
    from rest_framework import exceptions
    
    class MyPermission(BasePermission):
        message = {'code': 10001, 'error': '你没权限'}   #没有权限的报错信息
        def has_permission(self, request, view): #使用多条数据的时候
            if request.user:   
                return True   #有权限
            # raise exceptions.PermissionDenied({'code': 10001, 'error': '你没权限'})
            return False      #没有权限
        
        def has_object_permission(self, request, view, obj):   #使用单条数据的时候
            return False
    
        
    当应用了全局的权限,有一个视图不需要权限在改视图定义权限为空列表: permission_classes = [MyPermission,]
    
    settings中的权限配置(全局)
    DEFAULT_PERMISSION_CLASSES = ["api.views.auth.MyPermission",]
    

    局部使用

    from api.views.account import MyPermission
    # 文章的展示,添加
    class ArticleView(ListAPIView,CreateAPIView):
        permission_classes = [MyPermission,]#一个视图的权限应用,在settings中就不用再写权限配置
        def get_serializer_class(self):
            if self.request.method == 'GET':
                return ArticleSerializer
            elif self.request.method == 'POST':
                return AddArticleSerializer
    

    权限的源码分析

    执行流程

    1.请求进来执行dispatch方法中的initialize_request方法
        def initialize_request(self, request, *args, **kwargs):
            parser_context = self.get_parser_context(request)
    
            return Request(
                request,
                parsers=self.get_parsers(),
                authenticators=self.get_authenticators(),
                negotiator=self.get_content_negotiator(),
                parser_context=parser_context
            )
    
    2.执行inital
        def initial(self, request, *args, **kwargs):
    		.......略过的代码
            version, scheme = self.determine_version(request, *args, **kwargs)
            request.version, request.versioning_scheme = version, scheme
    
            self.perform_authentication(request) #认证函数
            self.check_permissions(request)  #权限函数
            self.check_throttles(request)
    
    3.执行check_throttles(request)
        def check_permissions(self, request):
    
            for permission in self.get_permissions():
                if not permission.has_permission(request, self):
                    self.permission_denied(
                        request, message=getattr(permission, 'message', None)
                    )
     
    def get_permissions(self):
    
            return [permission() for permission in self.permission_classes]
    get_permissions是已经封装到request中的权限对象
    
    4.执行权限对象中的has_permission
    class MyPermission(BasePermission): #自定义的权限类
        message = '你没有权限'
        def has_permission(self, request, view):  #获取多个对象的时候执行
            if request.method == "GET":  #对请求进行权限认证,get请求有权限,代表可以看,不可以进行增删改查
                return True
            else:
    			#对增删改查有权限
                if request.user and request.auth: #判断该用户情况在进行判断
    
                    return True
                return False #无权限
    
        def has_object_permission(self, request, view, obj): #获取单个对象的时候执行
            return self.has_permission(request, view)
    

    概括

    1.请求进来时,先执行dispatch方法,对的request进行重新封装
    2.执行get_permissions(),循环permission_classes得到这个权限类的对象,把对象也封装进去
    3.循环这个权限对象列表,执行每个对象中的has_permission方法,返回True就代表有权限,False代表没有权限
    # has_permission是自己定义权限类中的方法,重写该方法
    
  • 相关阅读:
    layui 参照赋值的两种方式
    c笔记
    Linux操作系统笔记
    make笔记
    Gcc如何知道文件类型。
    #include <xxx.h>和#include "xxx.h"的区别
    GCC编译流程
    c++ Socket客户端和服务端示例版本三(多线程版本)
    c++ Socket客户端和服务端示例版本二
    c++ Socket客户端和服务端示例版本一
  • 原文地址:https://www.cnblogs.com/tangjian219/p/11913843.html
Copyright © 2011-2022 走看看