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

DRF DjangoModelPermissions 拒绝已授权认证用户访问问题排查

DRF接口返回403权限拒绝排查修复方案

你当前已完成的验证场景如下:

  • 权限配置核查:核查权限配置内容
  • Shell授权操作记录:通过Shell授予权限
  • Postman接口测试返回权限拒绝:Postman接口测试
  • 当前视图代码:
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [DjangoModelPermissions]

class UserDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [DjangoModelPermissions]

按以下优先级排查修复即可:

1. 先排查认证环节是否正常

DjangoModelPermissions 生效的前提是请求能通过认证类识别到合法登录用户,拿不到有效用户时会直接判定为匿名用户返回403,哪怕后台已经给对应用户分配了权限也不会生效。

  • 调试方法:在视图中加入打印逻辑输出request.user,如果返回AnonymousUser,说明认证环节失效:
    • 用Session认证的场景,检查Postman是否携带了有效会话Cookie、开启跨请求保持会话,POST/PUT/DELETE请求是否携带合法CSRF Token
    • 用Token/JWT认证的场景,检查请求头Authorization的格式、Token值是否正确,是否存在Token过期、拼写错误问题

如果超级用户账号访问依旧返回403,可直接判定为认证环节失效或代码配置未生效,优先排查认证逻辑和代码缩进问题。

2. 排查权限缓存不生效问题

Django会在用户登录时把全量权限缓存到会话中,如果你是在用户已经登录的状态下,通过Shell或者后台给用户新增权限,当前会话里的权限数据不会自动更新,会一直判定为无权限。

  • 修复方法:让对应用户退出登录后重新登录,拉取最新的权限数据再测试;如果用了外部权限缓存(比如Redis存权限),先清空对应缓存再测试。
  • 权限有效性验证:在Shell中对应用户下执行print(user.get_all_permissions()),确认输出的权限集合中包含当前请求需要的权限标识。

3. 核对权限映射规则与权限标识

DjangoModelPermissions 默认的权限映射规则不包含GET类请求的查看权限校验,具体对应关系如下:

请求方法所需权限标识格式
POST{app_label}.add_{model_name}
PUT/PATCH{app_label}.change_{model_name}
DELETE{app_label}.delete_{model_name}
GET/HEAD/OPTIONS无默认权限要求
  • 如果你是GET请求被拦截,要么是全局配置了其他权限类拦截,要么是需要自定义权限类加入view权限校验,参考代码:
from rest_framework.permissions import DjangoModelPermissions

class DjangoModelPermsWithView(DjangoModelPermissions):
    perms_map = {
        'GET': ['%(app_label)s.view_%(model_name)s'],
        'HEAD': [],
        'OPTIONS': [],
        'POST': ['%(app_label)s.add_%(model_name)s'],
        'PUT': ['%(app_label)s.change_%(model_name)s'],
        'PATCH': ['%(app_label)s.change_%(model_name)s'],
        'DELETE': ['%(app_label)s.delete_%(model_name)s'],
    }
  • 核对权限标识的app_label和model_name完全匹配:如果用Django默认User模型,权限前缀是auth,比如auth.add_user;如果是自定义User模型在users应用下,前缀是users,标识错误的权限不会被识别。

4. 修复代码格式错误

你贴出的视图代码存在严重的缩进问题:Python类的属性必须相对class声明行缩进4个空格,当前代码中queryset、serializer_class、permission_classes 都和class行顶格对齐,根本不属于视图类的属性,会导致视图读取全局默认配置,权限类、查询集配置不生效。
修正后的正确代码格式:

class UserList(generics.ListCreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [DjangoModelPermsWithView] # 如需GET校验权限替换为自定义类

class UserDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [DjangoModelPermsWithView]

验证顺序

  1. 修正代码缩进,重启服务
  2. 打印request.user确认拿到的是目标授权用户
  3. 重新登录刷新权限缓存,确认user.get_all_permissions()返回对应权限
  4. 检查Postman认证参数传递正确
  5. 如果是GET请求,替换为带view权限校验的自定义权限类

内容的提问来源于stack exchange,提问作者Mr.Andor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:27:33