Django非Allauth路由中request.user.is_authenticated验证失效问题
问题诊断与解决方案
核心问题分析
你的问题本质是Allauth的AccountMiddleware仅针对自身视图处理X-Session-Token认证,不会自动为自定义API路由解析令牌并关联用户,导致非Allauth路由中request.user.is_authenticated始终为False。
解决方案步骤
1. 调整自定义中间件,手动处理令牌认证
修改你的BlockAnonymousUsersMiddleware,加入令牌验证逻辑,主动将用户绑定到request对象:
from django.http import JsonResponse from django.utils.deprecation import MiddlewareMixin from allauth.account.models import SessionToken from django.contrib.auth import get_user_model User = get_user_model() class BlockAnonymousUsersMiddleware(MiddlewareMixin): def process_request(self, request): protected_paths = ['/api/'] # 跳过Allauth自身路由,避免重复处理 if request.path.startswith('/accounts/'): return None for path in protected_paths: if request.path.startswith(path): # 从请求头提取会话令牌 session_token = request.headers.get('X-Session-Token') if not session_token: return JsonResponse({ 'status': 401, 'errors': [{'message': 'Authentication required'}] }) # 验证令牌有效性并关联用户 try: token_obj = SessionToken.objects.get(token=session_token) user = User.objects.get(pk=token_obj.user_id) request.user = user except (SessionToken.DoesNotExist, User.DoesNotExist): return JsonResponse({ 'status': 401, 'errors': [{'message': 'Invalid session token'}] }) # 最终校验用户认证状态 if not request.user.is_authenticated: return JsonResponse({ 'status': 401, 'errors': [{'message': 'User is not authenticated'}] }) return None
2. 确认关键配置正确性
- 自定义用户模型配置:确保
settings.py中指定了正确的用户模型路径:AUTH_USER_MODEL = 'users.UserProfile' # 替换为你的实际用户模型路径 - 跨域请求头允许:如果前端是跨域请求,需在
settings.py中添加允许X-Session-Token:CORS_ALLOW_HEADERS = [ # 其他已配置的请求头 'x-session-token', ]
3. (可选)升级为新式中间件(Django 3.1+)
Django 3.1及以上版本推荐使用无继承的新式中间件写法:
from django.http import JsonResponse from allauth.account.models import SessionToken from django.contrib.auth import get_user_model User = get_user_model() class BlockAnonymousUsersMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): protected_paths = ['/api/'] if request.path.startswith('/accounts/'): return self.get_response(request) for path in protected_paths: if request.path.startswith(path): session_token = request.headers.get('X-Session-Token') if not session_token: return JsonResponse({ 'status': 401, 'errors': [{'message': 'Authentication required'}] }) try: token_obj = SessionToken.objects.get(token=session_token) user = User.objects.get(pk=token_obj.user_id) request.user = user except (SessionToken.DoesNotExist, User.DoesNotExist): return JsonResponse({ 'status': 401, 'errors': [{'message': 'Invalid session token'}] }) if not request.user.is_authenticated: return JsonResponse({ 'status': 401, 'errors': [{'message': 'User is not authenticated'}] }) response = self.get_response(request) return response
关键说明
Allauth的AccountMiddleware仅在处理自身视图(如登录、注册)时自动解析X-Session-Token,自定义路由需要手动实现令牌验证逻辑,将用户绑定到request对象后,后续视图和中间件就能正确获取用户的认证状态。
内容的提问来源于stack exchange,提问作者Olatunji Hammed
相关产品推荐
相关产品推荐

