zoukankan      html  css  js  c++  java
  • Django(63)drf权限源码分析与自定义权限

    前言

    上一篇我们分析了认证的源码,一个请求认证通过以后,第二步就是查看权限了,drf默认是允许所有用户访问
     

    权限源码分析

    源码入口:APIView.py文件下的initial方法下的check_permissions

    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),
                    code=getattr(permission, 'code', None)
                )
    

    权限在get_permissions方法中获取到,源码如下:

    def get_permissions(self):
          """
          实例化并返回此视图所需的权限列表。
          """
          return [permission() for permission in self.permission_classes]
    

    permission_classes又等于api_settings.DEFAULT_PERMISSION_CLASSES,所以我们去settings.py文件中查找

    'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.AllowAny',
        ],
    

    我们会发现drf默认的权限是AllowAny,我们去看下源码:

    class AllowAny(BasePermission):
        """
        允许任意访问。这不是严格要求的,因为您可以使用空的 permission_classes 列表,但它很有用,因为它使意图更加明确。
        """
    
        def has_permission(self, request, view):
            return True
    

    我们可以看到AllowAny继承自BasePermission,然后定义了has_permission方法,返回值为True

    drf为我们提供了4个系统权限认证:

    1. AllowAny
    认证规则全部返回True:`return True`
        游客与登录用户都有所有权限
    
    2. IsAuthenticated
    认证规则必须有登录的合法用户:`return bool(request.user and request.user.is_authenticated)`
        游客没有任何权限,登录用户才有权限
    
    3. IsAdminUser
    认证规则必须是:`return bool(request.user and request.user.is_staff)`
        游客没有任何权限,登录用户才有权限
    
    4. IsAuthenticatedOrReadOnly
        认证规则必须是只读请求或者是合法用户无限制
            return bool(
                request.method in SAFE_METHODS or
                request.user and
                request.user.is_authenticated
            )
            游客只读,合法用户无限制
    

    自定义认证类

    1. 创建继承BasePermission的权限类
    2. 实现has_permission方法
    3. 实现体根据权限规则 确定 有无权限
    4. 进行全局或局部配置(一般采用局部配置)

    权限规则
    满足设置的用户条件,代表有权限,返回True
    不满足设置的用户条件,代表有权限,返回False

    自定义权限

    from django.contrib.auth.models import Group
    from rest_framework.permissions import BasePermission
    
    
    class MyPermissions(BasePermission):
        def has_permission(self, request, view):
            rule1 = request.method in ['GET', 'OPTIONS', 'HEAD']
            group = Group.objects.filter(name="管理员").first()
            groups = request.user.groups.all()
            rule2 = group in groups
            rule3 = group and groups
            return rule1 or (rule2 and rule3)
    

    以上定义了3条规则

    • rule1:请求方法是GETOPTIONSHEAD游客和用户都可以访问
    • rule2:当前用户如果有多个分组,其中必须有一个分组是管理员
    • rule3:管理员分组必须存在,用户必须在分组中

    接下里我们定义视图

    class TestView(APIView):
        permission_classes = [MyPermissions]
    
        def get(self, request, *args, **kwargs):
            print(request.user)
            return APIResponse(data_msg="所有用户都可以访问")
    
        def post(self, request, *args, **kwargs):
            print(request.user)
            return APIResponse(data_msg="只有管理员用户可以访问")
    

    视图中只是添加了permission_classes = [MyPermissions]属与局部配置,也就是自定义的权限只针对此视图,其他视图还是默认的全局配置,如果我们还有其他的关于权限的需求,只需要在自定义的权限类中写逻辑即可

  • 相关阅读:
    QT5编程入门教程
    bstr_t与BSTR
    Android Studio 更改APP图标
    Indy服务器关闭所有客户端连接
    使用高德地图API
    内网渗透——Hadoop未授权访问getshell
    内网渗透——struts2远程任意代码执行(s2-046)
    工具使用——cobalt strike使用
    工具使用——docker使用
    漏洞复现——weblogic任意文件上传(cve-2018-2894)
  • 原文地址:https://www.cnblogs.com/jiakecong/p/14882036.html
Copyright © 2011-2022 走看看