【Dv3Admin】工具权限配置文件解析

接口级权限控制是后台系统安全防护的核心手段。基于用户角色、请求路径与方法进行细粒度授权,可以有效隔离不同用户的数据访问范围,防止越权操作,保障系统整体稳定性。

本文解析 dvadmin/utils/permission.py 模块,重点关注其在匿名用户拦截、超级管理员放行、普通管理员控制以及动态接口权限校验中的具体实现,探讨模块结构设计与应用边界。

文章目录

permission.py

系统基于 Django 和 DRF 构建后台 API 服务,dvadmin/utils/permission.py 模块提供了自定义权限控制机制。针对不同用户身份(匿名用户、超级管理员、普通管理员、自定义角色权限)分别实现了独立的权限校验类。模块通过匹配接口路径和请求方法判断用户是否有访问权限,强化了后端接口的安全防护。

项目特点 描述
技术栈 Django + DRF 自定义权限体系
功能定位 接口级权限控制、角色权限校验、匿名访问控制
验证方式 请求地址 + 请求方法双重校验
白名单机制 支持接口白名单,无需角色授权即可访问

dvadmin/utils/permission.py 文件定义了多种权限校验策略,覆盖了匿名用户拒绝、超级管理员全通、普通管理员通行、基于角色接口权限控制等多种场景。自定义的 CustomPermission 类根据接口地址与请求方式匹配用户拥有的接口权限列表,并支持接口白名单放行,确保访问控制灵活可控。同时辅助函数如 ValidationApiReUUID 提供接口动态校验支持,增强对 RESTful 风格接口的兼容性。

模块职责 说明
匿名用户权限拦截 AnonymousUserPermission 限制未登录用户访问接口
超级管理员通行 SuperuserPermission 赋予超级管理员无条件访问所有接口权限
普通管理员通行 AdminPermission 赋予管理角色基本权限
基于接口权限控制 CustomPermission 根据接口地址和请求方法判断是否有权限访问
接口路径动态匹配支持 替换 URL 中的动态参数(如 {id})支持正则匹配
接口白名单机制 允许配置无需授权即可访问的接口,提升接口开放性和灵活性

在需要精细化控制 API 访问权限的后台系统中,dvadmin/utils/permission.py 提供的权限体系可以灵活应用于不同模块。适用于登录鉴权、角色授权控制、匿名用户拦截、接口白名单管理等场景,有效保证系统接口安全性,同时支持多角色、多接口、多方法的细粒度权限分配。

使用场景 说明
后台接口统一权限校验 不同角色用户访问接口时自动判断是否有权限
限制匿名访问 未登录用户尝试访问受限接口时自动拒绝
超级管理员快速通行 超级管理员无需逐一配置权限,默认拥有全部访问权限
动态 URL 接口权限校验 适配 RESTful 动态接口路径如 /user/{id}/edit/
配置系统公共接口白名单 登录、注册等接口无需授权也可访问,提升用户体验

项目源码解析

接口权限校验工具函数

用于正则匹配当前请求接口与已有权限接口模板,判断是否拥有访问权限。接口模板中 {id} 部分动态替换成正则表达式,支持灵活的接口路径验证。属于基础工具函数,可在多种权限控制场景下复用。

python 复制代码
def ValidationApi(reqApi, validApi):
    if validApi is not None:
        valid_api = validApi.replace('{id}', '.*?')
        matchObj = re.match(valid_api, reqApi, re.M | re.I)
        if matchObj:
            return True
        else:
            return False
    else:
        return False

匿名用户权限验证类

阻止未登录的匿名用户访问需要认证的接口。判断请求用户是否为 AnonymousUser 类型,若是则拒绝访问。主要用于保护需要登录才能访问的系统模块。

python 复制代码
class AnonymousUserPermission(BasePermission):
    def has_permission(self, request, view):
        if isinstance(request.user, AnonymousUser):
            return False
        return True

超级管理员权限验证类

允许系统中的超级管理员无条件访问所有接口。通过 request.user.is_superuser 判断用户身份,快速放行,降低权限控制开销。

python 复制代码
class SuperuserPermission(BasePermission):
    def has_permission(self, request, view):
        if isinstance(request.user, AnonymousUser):
            return False
        if request.user.is_superuser:
            return True

管理员权限验证类

允许具有管理员角色标记或超级管理员身份的用户访问接口。综合角色属性 admin 字段判断权限,适合细粒度区分系统普通用户与管理员的使用场景。

python 复制代码
class AdminPermission(BasePermission):
    def has_permission(self, request, view):
        if isinstance(request.user, AnonymousUser):
            return False
        is_superuser = request.user.is_superuser
        is_admin = request.user.role.values_list('admin', flat=True)
        if is_superuser or True in is_admin:
            return True

用于在接口权限匹配中,将动态的 UUID 字段统一替换成正则表达式,保证路径格式标准化,提升接口匹配的准确性。主要服务于接口动态参数场景下的权限验证。

python 复制代码
def ReUUID(api):
    pattern = re.compile(r'[a-f\d]{4}(?:[a-f\d]{4}-){4}[a-f\d]{12}/$')
    m = pattern.search(api)
    if m:
        res = api.replace(m.group(0), ".*/")
        return res
    else:
        return None

自定义综合权限验证类

系统核心权限控制模块,综合判断接口白名单、角色绑定按钮接口权限,决定请求是否放行。支持动态参数路径处理、请求方法校验、多角色权限叠加,具有较高灵活性和扩展性。依赖 ApiWhiteList 表管理无需授权的接口,RoleMenuButtonPermission 表管理角色拥有的接口权限,是接口级权限控制的重要组成部分。

python 复制代码
class CustomPermission(BasePermission):
    def has_permission(self, request, view):
        if isinstance(request.user, AnonymousUser):
            return False
        if request.user.is_superuser:
            return True
        else:
            api = request.path
            method = request.method
            methodList = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH']
            method = methodList.index(method)

            api_white_list = ApiWhiteList.objects.values(permission__api=F('url'), permission__method=F('method'))
            api_white_list = [
                str(item.get('permission__api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str(item.get('permission__method')) + '$'
                for item in api_white_list if item.get('permission__api')
            ]

            if not hasattr(request.user, "role"):
                return False

            role_id_list = request.user.role.values_list('id', flat=True)
            userApiList = RoleMenuButtonPermission.objects.filter(role__in=role_id_list).values(
                permission__api=F('menu_button__api'), permission__method=F('menu_button__method'))

            ApiList = [
                str(item.get('permission__api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str(item.get('permission__method')) + '$'
                for item in userApiList if item.get('permission__api')
            ]

            new_api_list = api_white_list + ApiList
            new_api = api + ":" + str(method)
            for item in new_api_list:
                matchObj = re.match(item, new_api, re.M | re.I)
                if matchObj:
                    return True
            else:
                return False

应用案例

接口级权限控制在后台管理系统中的实际应用

在后台管理系统中,接口级权限控制是保障系统安全性和操作权限合规性的核心手段。dvadmin/utils/permission.py 模块通过自定义权限类,灵活处理不同角色和请求路径的权限校验,实现了从匿名用户拦截、超级管理员放行、普通管理员控制到基于角色的动态权限校验的多层级安全防护。模块支持路径参数的动态匹配,并能够与接口白名单机制结合,提供灵活的接口访问策略。
是 否 是 否 匹配成功 匹配失败 请求用户身份识别 是否为匿名用户? 返回无权限错误 是否为超级管理员? 放行 查询角色绑定接口权限 构建接口路径+方法标识符 与权限表中接口路径模板进行正则匹配

在实际应用中,系统会根据不同用户身份类型(如普通用户、管理员、超级管理员)自动匹配权限控制策略,避免越权操作,确保系统的数据隔离性和权限合规性。

权限校验与接口放行的业务实现

在后台系统中,当用户尝试访问某个受保护的接口时,系统会根据当前用户的角色、请求路径和方法动态判断是否允许访问。例如,假设用户尝试访问 GET /api/users/ 接口,系统会通过 CustomPermission 类的逻辑检查用户的角色是否拥有访问该接口的权限:

python 复制代码
class CustomPermission(BasePermission):
    def has_permission(self, request, view):
        if isinstance(request.user, AnonymousUser):
            return False
        if request.user.is_superuser:
            return True
        else:
            api = request.path
            method = request.method
            methodList = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH']
            method = methodList.index(method)

            api_white_list = ApiWhiteList.objects.values(permission__api=F('url'), permission__method=F('method'))
            api_white_list = [
                str(item.get('permission__api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str(item.get('permission__method')) + '$'
                for item in api_white_list if item.get('permission__api')
            ]

            if not hasattr(request.user, "role"):
                return False

            role_id_list = request.user.role.values_list('id', flat=True)
            userApiList = RoleMenuButtonPermission.objects.filter(role__in=role_id_list).values(
                permission__api=F('menu_button__api'), permission__method=F('menu_button__method'))

            ApiList = [
                str(item.get('permission__api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str(item.get('permission__method')) + '$'
                for item in userApiList if item.get('permission__api')
            ]

            new_api_list = api_white_list + ApiList
            new_api = api + ":" + str(method)
            for item in new_api_list:
                matchObj = re.match(item, new_api, re.M | re.I)
                if matchObj:
                    return True
            else:
                return False

在该例中,CustomPermission 会首先检查用户是否是匿名用户,如果是,则拒绝访问;若用户为超级管理员,直接放行;对于普通用户,则会根据用户角色绑定的接口权限列表,判断是否匹配当前请求的路径和方法。如果接口不在白名单中且用户没有足够权限,访问会被拒绝。

超级管理员权限快速放行

超级管理员身份在系统中拥有完全的访问权限,模块通过以下逻辑快速判断超级管理员身份并放行所有请求,避免每次权限检查时都进行繁琐的权限验证:

python 复制代码
class SuperuserPermission(BasePermission):
    def has_permission(self, request, view):
        if isinstance(request.user, AnonymousUser):
            return False
        if request.user.is_superuser:
            return True

这样,超级管理员可以在不需要额外配置的情况下,访问系统中所有的 API 接口,无论接口是否有权限配置。

角色权限校验与动态接口控制

在更复杂的业务场景中,不同角色可能拥有不同的权限,例如某些用户只能访问特定的数据。AdminPermission 类允许管理角色的用户访问接口,具体通过用户的角色和权限数据进行判断:

python 复制代码
class AdminPermission(BasePermission):
    def has_permission(self, request, view):
        if isinstance(request.user, AnonymousUser):
            return False
        is_superuser = request.user.is_superuser
        is_admin = request.user.role.values_list('admin', flat=True)
        if is_superuser or True in is_admin:
            return True

该权限检查不仅考虑了用户是否是管理员,还通过角色的 admin 字段进一步验证是否具有访问该接口的权限,保证权限的细粒度控制。

接口白名单机制

在一些特殊场景下,部分接口不需要进行权限验证,常见的如登录、注册、验证码发送等。这些接口可以配置到白名单中,通过 ApiWhiteList 表管理,无需额外的权限控制。每次请求到达时,系统会检查当前接口是否属于白名单接口,如果是,则自动放行:

python 复制代码
api_white_list = ApiWhiteList.objects.values(permission__api=F('url'), permission__method=F('method'))

此机制大大简化了接口权限配置,避免了频繁修改权限逻辑的麻烦,同时提升了系统的可扩展性。

通过以上实现,dvadmin/utils/permission.py 模块提供了灵活、细粒度的权限控制机制,适用于不同角色、接口、请求方法的权限校验,且能够与动态路径、白名单机制结合,确保系统的安全性与可扩展性。

总结

模块以路径加请求方法为权限校验依据,结合角色与白名单机制,覆盖绝大多数后台接口访问控制需求。采用自定义权限类,配合动态 URL 匹配和接口正则替换,实现灵活兼容 RESTful 风格。整体结构清晰,具备较高的可扩展性与通用性。

权限匹配采用循环遍历方式,效率在接口量大时存在隐患。白名单与权限列表加载未作缓存处理,增加数据库压力。权限判断逻辑集中在单一类中,缺乏更细粒度的职责划分,后期维护和扩展难度较高。

相关推荐
weixin_4723394610 小时前
PostgreSQL优化实践:从查询到架构的性能提升指南
数据库·postgresql·django
新手村领路人16 小时前
Django数据库连接报错 django.db.utils.NotSupportedError: MySQL 8 or later is required
mysql·django
blues_C3 天前
九、【前后端联调篇】Vue3 + Axios 异步通信实战
vue.js·后端·django·axios·drf·测试平台
zhuyasen3 天前
当 Python 遇上 Go:Sponge 如何成为替代 Django/Flask 的理想选择
python·django·flask
KENYCHEN奉孝4 天前
Weather app using Django - Python
后端·python·django
编程自留地4 天前
第12次04 :首页展示用户名
数据库·python·django·商城
程序媛徐师姐5 天前
Python基于Django的主观题自动阅卷系统【附源码、文档说明】
python·django·python主观题自动阅卷系统·主观题自动阅卷系统·python主观题评分系统·主观题评分系统·主观题评分
声声codeGrandMaster5 天前
Django实现文件上传
数据库·后端·python·django
开开心心就好5 天前
能按需拆分 PDF 为多个文档的工具
javascript·python·智能手机·django·pdf·word·excel