DRF之权限组件源码分析
【一】权限组件介绍
- Django REST framework(DRF)中的权限组件用于控制API的访问权限。
- DRF内置了多个常用的权限类,同时也允许你创建自定义的权限类以满足特定需求。
【二】内置权限类
- IsAuthenticated:要求用户在访问API时进行身份验证,即用户必须登录。
- IsAdminUser:要求用户是管理员。
- IsAuthenticatedOrReadOnly:要求用户在写入数据(例如创建、更新、删除)之前进行身份验证,但允许未经身份验证的用户进行只读操作。
- IsOwnerOrReadOnly:通常用于处理对象级别的权限。它要求用户在对对象进行写入操作时是对象的所有者,但允许未经身份验证的用户进行只读操作。
【三】执行流程分析
- DRF的权限组件在视图类的
perform_authentication
方法之后执行。

| |
| |
| |
| self.check_permissions(request) |

| 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), |
| code=getattr(permission, 'code', None) |
| ) |
- DRF的身份验证组件(如Token、Session等)会验证用户的身份,并将用户信息添加到请求对象中。

- 权限组件开始执行。
- 它会检查请求对象中的用户信息,并根据所选的权限类来判断用户是否有权限访问视图。
| 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_permission
和 has_object_permission
两个方法,这些方法用于控制API的访问权限。
| from rest_framework.permissions import BasePermission |
| 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): |
| """ |
| 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 |
| |
| def has_object_permission(self, request, view, obj): |
| |
| return True |
【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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通