DRF使用BasicAuthentication校验权限时未识别认证用户问题
问题根因
- 两个组件的执行时序不匹配:
guardian.mixins.PermissionRequiredMixin是为Django原生类视图设计的权限组件,它的校验逻辑会在DRF的认证流程之前触发。而DRF的BasicAuthentication认证逻辑是在自身框架的请求处理流程中执行的,校验触发时DRF还未完成用户身份识别,request.user自然还是匿名用户。 - 继承顺序错误:当前视图的继承顺序将
PermissionRequiredMixin放在首位,会进一步优先执行Django体系的权限校验逻辑,跳过DRF的前置身份认证处理。
解决方案
方案一:使用DRF适配的权限类(推荐)
直接用DRF生态的权限类替代Guardian原生Mixin,避免时序冲突。如果你已经在settings.py中配置了Guardian的ObjectPermissionBackend作为权限后端,直接使用DRF内置的DjangoObjectPermissions即可,默认会匹配你设置的widget.view_widget权限规则:
from rest_framework.permissions import DjangoObjectPermissions from rest_framework.generics import RetrieveAPIView class WidgetDetail(RetrieveAPIView): serializer_class = WidgetSerializer permission_classes = [DjangoObjectPermissions]
方案二:保留Guardian Mixin,调整校验时序
如果你一定要使用PermissionRequiredMixin,可以重写视图的initial方法,将权限校验挪到DRF认证完成后执行:
from guardian.mixins import PermissionRequiredMixin from rest_framework.generics import RetrieveAPIView class WidgetDetail(RetrieveAPIView, PermissionRequiredMixin): serializer_class = WidgetSerializer permission_required = "widget.view_widget" return_403 = True def initial(self, request, *args, **kwargs): # 先执行DRF默认流程,完成身份认证 super().initial(request, *args, **kwargs) # 再执行Guardian权限校验 self.check_permissions(request)
额外排查点
- 确认
settings.py的REST_FRAMEWORK配置中,DEFAULT_AUTHENTICATION_CLASSES确实包含rest_framework.authentication.BasicAuthentication,如果是视图单独配置认证类,需确认当前视图的authentication_classes配置正确。 - 确认SPA发起的请求确实携带了符合规范的
Authorization请求头,格式为Basic <base64编码的用户名:密码字符串>,否则DRF不会触发BasicAuthentication的认证逻辑。
内容的提问来源于stack exchange,提问作者nehalem
相关产品推荐
相关产品推荐

