You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework基于用户组权限的API访问控制实现问询

如何通过组权限限制Django REST Framework的API访问?

当然可以实现!你现在的问题很明确:只配置了IsAuthenticated权限类——它只负责验证用户是否登录,完全没检查用户所在组的权限。咱们一步步来解决这个问题:

1. 先搞懂核心问题

Django REST Framework(DRF)的permission_classes是按顺序执行校验的,你现在的配置只做了“登录验证”这一步,所以不管用户有没有对应权限,只要登录就能访问API。要实现组权限控制,必须加上权限校验的逻辑。

2. 快速方案:用DRF自带的DjangoModelPermissions

如果你的权限是Django默认生成的模型权限(比如Can add mymodel、Can delete mymodel这类),直接用DRF自带的DjangoModelPermissions就能搞定,它会自动把HTTP方法和模型权限对应起来:

修改你的views.py:

from rest_framework.permissions import IsAuthenticated, DjangoModelPermissions

class MyApi(ModelViewSet):
    permission_classes = (IsAuthenticated, DjangoModelPermissions)
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

它的对应逻辑是:

  • GET/HEAD/OPTIONS 请求 → 检查Can view mymodel权限
  • POST 请求 → 检查Can add mymodel权限
  • PUT/PATCH 请求 → 检查Can change mymodel权限
  • DELETE 请求 → 检查Can delete mymodel权限

只要你给用户组分配了对应的权限,这个类会自动校验用户(或用户所在组)是否拥有该权限。

3. 灵活方案:自定义权限类(适配自定义权限)

如果你的权限是自定义的(比如你提到的Can add activity),那可以写一个自定义权限类,精准控制每个HTTP方法对应的权限:

先在permissions.py(可以新建这个文件)里写权限类:

from rest_framework import permissions

class GroupBasedPermission(permissions.BasePermission):
    def has_permission(self, request, view):
        # 先确保用户已登录
        if not request.user.is_authenticated:
            return False
        
        # 定义HTTP方法和对应权限编码的映射
        # 注意:Django权限的编码格式是 `{app_label}.{permission_codename}`
        method_perm_map = {
            'GET': 'your_app.view_activity',
            'POST': 'your_app.add_activity',
            'PUT': 'your_app.change_activity',
            'PATCH': 'your_app.change_activity',
            'DELETE': 'your_app.delete_activity'
        }
        
        # 获取当前请求需要的权限
        required_perm = method_perm_map.get(request.method)
        if not required_perm:
            return False
        
        # 检查用户是否拥有该权限(包括组权限)
        return request.user.has_perm(required_perm)

然后修改views.py使用这个自定义权限:

from .permissions import GroupBasedPermission
from rest_framework.permissions import IsAuthenticated

class MyApi(ModelViewSet):
    permission_classes = (IsAuthenticated, GroupBasedPermission)
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

4. 排查你之前的权限不生效问题

你说已经给组分配了权限、把用户加进组,但还是能访问受限API,大概率是这几个原因:

  • 没在视图里添加权限校验类:你之前的代码只有IsAuthenticated,根本没做权限检查
  • 权限编码写错了:Django的权限编码是{app_label}.{action}_{model_name},比如你的模型是Activity,删除权限的编码是your_app.delete_activity,要确保组里分配的权限和代码里检查的一致
  • 缓存问题:Django会缓存权限,修改权限后可能需要重启服务器,或者在Django shell里执行from django.contrib.auth.models import Permission; Permission.objects.all().update()刷新缓存
  • 用户直接拥有权限:如果用户自己被单独分配了权限(不是通过组),会覆盖组权限的限制,要确保用户没有直接的权限分配

5. 测试验证

配置好后,用你的user_xx用户(只拥有add_activity权限)去访问DELETE接口,应该会返回403 Forbidden,这就符合你的预期了。

内容的提问来源于stack exchange,提问作者JPG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:41:32