美文网首页
权限源码流程

权限源码流程

作者: 小吉头 | 来源:发表于2020-07-21 11:40 被阅读0次

权限模块

rest_framework.permissions是restframework提供的权限模块,其他权限类都要继承BasePermission

权限验证流程

dispatch()方法中,有下面两段关键代码:

...
#封装Request对象
request = self.initialize_request(request, *args, **kwargs)
...
#认证、权限、限流验证
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.
        version, scheme = self.determine_version(request, *args, **kwargs)
        request.version, request.versioning_scheme = version, scheme

        # Ensure that the incoming request is permitted
        self.perform_authentication(request) #认证
        self.check_permissions(request) #权限
        self.check_throttles(request) #限流

下面看下权限的流程

class APIView(View):
    ...
    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES#跟认证流程类似,如果在settings.py中定义了`DEFAULT_PERMISSION_CLASSES`会覆盖restframework settings.py中的定义
    ...

    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)


    def get_permissions(self):
        """
        Instantiates and returns the list of permissions that this view requires.
        """
        return [permission() for permission in self.permission_classes]

    
     def check_permissions(self, request):
        """
        Check if the request should be permitted.
        Raises an appropriate exception if the request is not permitted.
        """
        for permission in self.get_permissions():
            if not permission.has_permission(request, self):
                self.permission_denied(
                    request, message=getattr(permission, 'message', None)
                )

本例settings.py定义:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES':[
        'rest_framework.permissions.IsAuthenticated',
        'rest_framework.permissions.IsAdminUser'
    ]
}

所以for permission in self.get_permissions():中的self.get_permissions()就是[IsAuthenticated(),IsAdminUser()]

遍历list中对象,调用has_permission(request, self)进行认证,self指向封装的Request对象。返回False,权限认证失败。可以定义message属性实现权限验证失败自定义提示。
IsAuthenticated类为例,查看源码:

class BasePermission(metaclass=BasePermissionMetaclass):
    """
    A base class from which all permission classes should inherit.
    """

    def has_permission(self, request, view):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True

    def has_object_permission(self, request, view, obj):#RetrieveModelMixin获取单个对象,self.get_object()实际调用的是GenericAPIView中的get_object(),里面的self.check_object_permissions(self.request, obj)会检测是否有操作该对象的权限
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True


#认证通过才返回True
class IsAuthenticated(BasePermission):
    """
    Allows access only to authenticated users.
    """

    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated)

自定义权限类

根据验证认证的规则,自定义认证类,继承自BasePermission
utils目录下新建permission.py

from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):

    message = "用户没有访问权限"#自定义权限认证失败提示

    def has_permission(self, request, view):
        if request.user == "xiaobai":
            return True
        return False

全局配置

如果想让所有视图都必须要认证后才能访问,可以在django项目的settings.py中设置REST_FRAMEWORK变量,即本篇开始时写的,修改成自定义的认证类:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES':['utils.permission.MyPermission']
}

局部配置

如果只是某个视图使用,可以在类中定义属性,比如:permission_classes = [MyPermission]
如果不需要认证,可以写成permission_classes = []

相关文章

  • 权限源码流程

    权限模块 rest_framework.permissions是restframework提供的权限模块,其他权限...

  • Linux MySQL5.7源码安装--未完成

    问题 由于主机未连接外网并且只有普通权限用户,想通过源码安装MySQL5.7 流程 1、官网下载MySQL源码 2...

  • Django drf版本控制

    源码流程 和认证的流程一样,进入initial(request)在认证,权限,节流前先执行了这两句函数,获取到ve...

  • Django认证源码流程,权限流程

    首先打开APIView 然后点击在里面找到dispath方法下面这个方法如图 然后我们开始重写这个方法如下图 下面...

  • DevStack部署

    部署整体流程 安装git 使用git下载DevStack源码 使用创建用户脚本创建用户 设置用户权限,并移动dev...

  • 处理路由和权限映射element-admin

    你现在项目中如何处理路由和权限映射的? 动态路由分析动态路由流程图 动态路由源码分析生成动态路由的源码位于 src...

  • 2018-08-30

    横向流程图源码格式: 竖向流程图源码格式: 标准流程图源码格式: 标准流程图源码格式(横向): UML时序图源码样...

  • typora流程图画法

    1.1 流程图 1.1 横向流程图源码格式: 1.2 竖向流程图源码格式: 1.3 标准流程图源码格式: 1.4 ...

  • 02--对象本质01--alloc本质

    [TOC] alloc 流程 alloc 流程 1. alloc 流程1 这个流程是按照源码进行绘制,包含了源码中...

  • 01--方法本质01--方法初探

    [TOC] alloc 流程 alloc 流程 1. alloc 流程1 这个流程是按照源码进行绘制,包含了源码中...

网友评论

      本文标题:权限源码流程

      本文链接:https://www.haomeiwen.com/subject/yccjcktx.html