首页 > 编程语言 >DRF之权限组件源码分析

DRF之权限组件源码分析

时间:2024-04-23 19:23:23浏览次数:18  
标签:permission self request 用户 视图 源码 组件 权限 DRF

DRF之权限组件源码分析

【一】权限组件介绍

  • Django REST framework(DRF)中的权限组件用于控制API的访问权限。
  • DRF内置了多个常用的权限类,同时也允许你创建自定义的权限类以满足特定需求。

【二】内置权限类

  • IsAuthenticated:要求用户在访问API时进行身份验证,即用户必须登录。
  • IsAdminUser:要求用户是管理员。
  • IsAuthenticatedOrReadOnly:要求用户在写入数据(例如创建、更新、删除)之前进行身份验证,但允许未经身份验证的用户进行只读操作。
  • IsOwnerOrReadOnly:通常用于处理对象级别的权限。它要求用户在对对象进行写入操作时是对象的所有者,但允许未经身份验证的用户进行只读操作。

【三】执行流程分析

  • DRF的权限组件在视图类的 perform_authentication 方法之后执行。

image

# 执行视图类中的 校验函数,也就是我们重写的has_permission 方法
# 完成对权限的校验 , 返回 True 或 False 供其他方法进一步判断
# 当返回True 时 ,可以返回一个 User 对象
self.check_permissions(request)
  • 用户发送API请求。

image

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():
        
        # 判断权限类中是否重写了 has_permission 校验方法
        # 如果没有重写则抛出异常
        if not permission.has_permission(request, self):
            self.permission_denied(
                request,
                message=getattr(permission, 'message', None),
                code=getattr(permission, 'code', None)
            )
  • DRF的身份验证组件(如Token、Session等)会验证用户的身份,并将用户信息添加到请求对象中。

image

  • 权限组件开始执行。
    • 它会检查请求对象中的用户信息,并根据所选的权限类来判断用户是否有权限访问视图。
def get_permissions(self):
    """
        Instantiates and returns the list of permissions that this view requires.
        """
    # 将每一个权限类对象返回给上层调用
    return [permission() for permission in self.permission_classes]
  • 如果权限验证失败,DRF将返回HTTP 403 Forbidden响应。

【四】内置权限类源码分析

【0】BasePermission

  • BasePermission 类是所有自定义权限类的基类。
  • 它定义了 has_permissionhas_object_permission 两个方法,这些方法用于控制API的访问权限。
from rest_framework.permissions import BasePermission
class BasePermission(metaclass=BasePermissionMetaclass):
    """
    A base class from which all permission classes should inherit.
    """
	
    # 视图级别的权限检查,它接受 request 和 view 参数,
    # 在这个方法中编写自定义的权限逻辑来判断用户是否有权访问整个视图。
    def has_permission(self, request, view):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True
	
    # 对象级别的权限检查,它接受 request、view 和 obj 参数
    # 在这个方法中编写自定义的权限逻辑来判断用户是否有权访问特定对象(例如数据库中的某个记录)。
    def has_object_permission(self, request, view, obj):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True

【1】IsAuthenticated

  • 要求用户在访问API时进行身份验证,即用户必须登录。
from rest_framework.permissions import IsAuthenticated
class IsAuthenticated(BasePermission):
    """
    Allows access only to authenticated users.
    """

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

【2】IsAdminUser

  • 要求用户是管理员。
from rest_framework.permissions import IsAdminUser
class IsAdminUser(BasePermission):
    """
    Allows access only to admin users.
    """

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

【3】IsAuthenticatedOrReadOnly

  • 要求用户在写入数据(例如创建、更新、删除)之前进行身份验证,但允许未经身份验证的用户进行只读操作。
from rest_framework.permissions import  IsAuthenticatedOrReadOnly
class IsAuthenticatedOrReadOnly(BasePermission):
    """
    The request is authenticated as a user, or is a read-only request.
    """

    def has_permission(self, request, view):
        return bool(
            request.method in SAFE_METHODS or
            request.user and
            request.user.is_authenticated
        )

【4】IsOwnerOrReadOnly

  • 通常用于处理对象级别的权限。它要求用户在对对象进行写入操作时是对象的所有者,但允许未经身份验证的用户进行只读操作。

【五】权限组件使用步骤(固定用法)

【1】创建权限认证类

  • 创建一个自定义的权限认证类,并让它继承自BasePermission

【2】实现has_permission方法

  • 在这个方法中编写自定义的权限逻辑来判断用户是否有权访问整个视图。
  • 在类中写方法:has_permission
    • 如果有权限,就返回True
    • 如果没有权限,就返回False
    • 错误信息是self.message='字符串'

【3】权限认证逻辑

from rest_framework import permissions

class CustomPermission(permissions.BasePermission):
    def has_permission(self, request, view):
        # 在这里编写视图级别的权限逻辑
        return True  # 或者根据需求返回 True 或 False

    def has_object_permission(self, request, view, obj):
        # 在这里编写对象级别的权限逻辑
        return True  # 或者根据需求返回 True 或 False

【4】使用权限认证类

  • 在视图类中,使用认证类

(1)局部使用

  • 在视图类中添加permission_classes属性,并将所需的权限认证类作为其值
  • 这样,在该视图类中只会应用指定的权限认证类。
# 权限认证
class UserDetailView(APIView):
    permission_classes = [AdminPermission, ]

(2)全局使用

  • 在配置文件(一般是settings.py)中进行全局配置,将权限认证类添加到DEFAULT_PERMISSION_CLASSES中。
  • 这样,在所有视图类中都会应用该权限认证类。
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'app01.permission.CustomPermission'
    ],
}

(3)全局使用/局部禁用

  • 当认证组件被全局配置后,可以在视图类中禁用全局认证组件,以实现局部禁用。
    • 如果权限认证组件被全局配置,你仍然可以在某个视图类中禁用全局的权限认证,实现局部禁用的效果。
    • 只需在该视图类中将permission_classes属性设置为空列表即可。
# 权限认证 - 局部禁用
class UserDetailView(APIView):
    permission_classes = []

(4)权限认证类的使用顺序

  • 先局部,在视图类定义的 permission_classes
  • 再全局,在DRF中自己配置的 DEFAULT_PERMISSION_CLASSES
  • 最后是,DRF默认配置中的 DEFAULT_PERMISSION_CLASSES

标签:permission,self,request,用户,视图,源码,组件,权限,DRF
From: https://www.cnblogs.com/ssrheart/p/18153602

相关文章

  • DRF之Request源码分析
    DRF之Request源码分析【一】路由入口fromdjango.contribimportadminfromdjango.urlsimportpathfrombookimportviewsurlpatterns=[path('admin/',admin.site.urls),path('test/',views.TestView.as_view()),path('test_http/&#......
  • 渲染 | Gaussian Splatting 源码解析
    TODO:GS组成pointcloudrenderflowoptimize仓库结构仓库由C++/CUDA和Python组成,CUDA包括diff-rasterization,Python包括optimize。CUDA部分依赖glm,只用了glm的vector数据类型。Rendering(C++/CUDAPart)Python-CUDA接口CUDA向Python暴露的就......
  • 面试官:在原生input上面使用v-model和组件上面使用有什么区别?
    前言还是上一篇面试官:来说说vue3是怎么处理内置的v-for、v-model等指令?文章的那个粉丝,面试官接着问了他另外一个v-model的问题。面试官:vue3的v-model都用过吧,来讲讲。粉丝:v-model其实就是一个语法糖,在编译时v-model会被编译成:modelValue属性和@update:modelValue事件。一......
  • Vue路由传值-路由组件传值
    在路由配置中设置需要传递参数的路由,并在路由路径中定义参数占位符:点击查看代码constroutes=[{path:'/user/:id',name:'user',component:UserComponent}];在触发路由跳转时,通过router.push方法传递参数:点击查看代码this.$router.push(......
  • 【Lua】源码编译
    1、准备工作1、下载lua源码在Lua官网下载指定版本的Lua源码。2、下载依赖库readline、ncurses在readline官网下载readline源码;在ncurses官网下载ncurses源码。2、编译readline将readline源码放到环境上并解压。执行以下命令安装./configuremakemakeinstall3、编译ncu......
  • SpringBoot3使用自带日志组件Logback
    参考:https://blog.csdn.net/AIJXB/article/details/128602818pom.xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency>application.yaml配置l......
  • 界面组件DevExpress Blazor UI v23.2 - 支持.NET 8、全新的项目模版
    DevExpress BlazorUI组件使用了C#为BlazorServer和BlazorWebAssembly创建高影响力的用户体验,这个UI自建库提供了一套全面的原生BlazorUI组件(包括PivotGrid、调度程序、图表、数据编辑器和报表等)。DevExpress Blazor控件目前已经升级到v23.2版本了,新版本正式支持.NET8、拥......
  • Spring 源码阅读(二)IoC 容器初始化以及 BeanFactory 创建和 BeanDefinition 加载过程
    相关代码提交记录:https://github.com/linweiwang/spring-framework-5.3.33IoC容器三种启动方式XMLJavaSE:ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml")ApplicationContextcontext=newFileSystemXmlApplicationContext("C:/beans......
  • Next-Auth 源码解析
    Next-Auth源码解析简单介绍一下Next-Auth源码的结构目录简介我们看packages/next-auth/src,这个目录下面是根目录,我们会看到下面的结构--src--client//这个里面主要是封装了fetch这个方法--core//这个是主要的方法,/api/auth/xxx的api及页面都是在这个里面......
  • DRF之视图组件
    【四】视图组件图源:drf(详细)_51CTO博客_什么是drf【1】两个视图基类【1.1】APIView请在【View】中查看详细【1.2】GenericAPIView【1.2.1】常用类属性基本设置:以下属性控制着基本视图的行为。queryset用于从视图返回对象的查询结果集。通常,你必须设置此......