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
相关产品推荐
相关产品推荐

