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

Django自定义中间件对已登录用户仍返回AnonymousUser如何解决

问题原因

这个现象是DRF的认证执行时机和Django原生中间件的逻辑不匹配导致的:

  • Django自带的AuthenticationMiddleware仅处理Django原生的基于Session、Cookie的身份认证,只会从session中读取用户信息赋值给request.user,不会处理DRF的自定义认证方案(比如Token、JWT、OAuth2等)。
  • DRF的认证逻辑是绑定在视图层执行的,会在视图的dispatch方法运行阶段才触发你配置的认证类完成校验,再给request对象赋值用户信息。所以中间件在调用视图之前的阶段,DRF的认证还未执行,拿到的自然是AnonymousUser。
  • 你在视图内部、以及中间件调用视图之后的阶段能拿到正确的用户,就是因为此时DRF的认证流程已经执行完成了。
解决方法

如果需要在中间件阶段就获取DRF认证后的用户,可以手动在中间件中提前触发DRF的认证逻辑,示例如下:

from rest_framework.request import Request
from rest_framework.views import APIView

class DisallowLoggedInUsers:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 手动触发DRF认证流程
        drf_request = Request(request)
        authenticators = APIView().get_authenticators()
        for auth_class in authenticators:
            try:
                auth_result = auth_class.authenticate(drf_request)
                if auth_result:
                    request.user, _ = auth_result
                    break
            except Exception:
                continue
        
        # 原有逻辑不变
        print("in interceptor before response")
        print("user: ", request.user)
        print("is_authenticated?: ", request.user.is_authenticated)

        response = self.get_response(request)

        print("in interceptor after response")
        print("user: ", request.user)
        print("is_authenticated?: ", request.user.is_authenticated)

        return response

上述代码会遍历你配置的所有DRF认证类依次尝试认证,只要有一个认证成功就会给request.user赋值,认证失败则保持原有的AnonymousUser,不影响原有逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 09:54:05