如何在Django REST Framework中添加自定义权限与基于角色的访问控制
Django REST Framework 自定义权限与基于角色的访问控制实现步骤
基于你提供的模型代码,具体实现按以下步骤操作:
1. 配置自定义用户模型
首先需要在项目settings.py中注册你自定义的User模型,替换Django默认的用户体系:
# settings.py 新增配置 AUTH_USER_MODEL = "你的应用名称.User" # 把“你的应用名称”替换为存放上述models.py的app名
2. 编写自定义权限类
在你的app目录下新建permissions.py文件,所有自定义权限都继承DRF的BasePermission基类,按需重写has_permission(全局接口权限校验)和has_object_permission(单对象权限校验)方法:
# permissions.py from rest_framework.permissions import BasePermission, SAFE_METHODS # 管理员权限 class IsAdmin(BasePermission): def has_permission(self, request, view): # 仅登录且是管理员的用户可访问 return request.user.is_authenticated and request.user.is_admin # 教师权限 class IsTeacher(BasePermission): def has_permission(self, request, view): return request.user.is_authenticated and request.user.is_teacher # 学生权限 class IsStudent(BasePermission): def has_permission(self, request, view): return request.user.is_authenticated and request.user.is_student # 学生仅可操作自身数据的对象级权限 class IsStudentSelf(BasePermission): def has_object_permission(self, request, view, obj): return request.user.is_authenticated and request.user.is_student and obj.user == request.user # 教师仅可查看学生信息、不可修改的权限示例 class TeacherCanViewStudent(BasePermission): def has_permission(self, request, view): if not (request.user.is_authenticated and request.user.is_teacher): return False # 仅允许读操作 return request.method in SAFE_METHODS
3. 视图层应用权限
权限可以全局配置,也可以单独给指定视图配置:
全局默认权限配置(可选)
在settings.py中配置DRF全局默认权限,所有未单独指定权限的视图都会默认使用该配置:
# settings.py REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', # 默认所有接口都需要登录 ] }
单视图配置权限
在需要特殊权限控制的视图中,通过permission_classes属性指定权限,支持多权限逻辑组合(|是或、&是且):
# views.py 示例 from rest_framework.viewsets import ModelViewSet from .models import Student, Teacher from .serializers import StudentSerializer, TeacherSerializer from .permissions import IsAdmin, IsTeacher, IsStudent, IsStudentSelf, TeacherCanViewStudent # 仅管理员可操作教师信息 class TeacherViewSet(ModelViewSet): queryset = Teacher.objects.all() serializer_class = TeacherSerializer permission_classes = [IsAdmin] # 管理员/教师可查看学生列表,学生仅可查看修改自己的信息 class StudentViewSet(ModelViewSet): queryset = Student.objects.all() serializer_class = StudentSerializer def get_permissions(self): if self.action == 'list': # 列表接口允许管理员和教师访问 return [IsAdmin | IsTeacher] elif self.action in ['retrieve', 'update', 'partial_update', 'destroy']: # 单对象操作允许管理员或者学生本人访问 return [IsAdmin | IsStudentSelf] return super().get_permissions()
4. 权限验证测试
使用不同角色的账号登录后访问对应接口,验证权限逻辑是否符合预期:
- 无权限用户访问受限接口应返回
403 Forbidden状态码 - 角色匹配的用户可正常访问对应接口
- 对象级权限需验证用户是否只能操作自身关联的数据
扩展说明
如果后续角色需要频繁新增、或者需要更细粒度的接口权限分配,可以直接复用Django自带的Group(用户组)和Permission(权限点)体系,把用户加入对应角色组,权限类中校验用户所在组即可,不用新增用户模型的布尔字段。
内容的提问来源于stack exchange,提问作者MOHAN SUNKA
相关产品推荐
相关产品推荐

