Django自定义用户部署后request.user返回AnonymousUser问题
问题分析与解决方案
1. 先排查Django会话Cookie的生产环境配置
部署到EC2+Nginx后,Cookie传递经常因为反向代理的配置问题,导致后续请求读不到会话信息。直接在settings.py里调整这些配置:
- 设对
SESSION_COOKIE_DOMAIN:填你的域名或者EC2公网IP,确保Cookie能被正确识别 - 开启
SESSION_COOKIE_SECURE = True(如果用HTTPS的话必须开,不然浏览器可能不传递Cookie) - 保留
SESSION_COOKIE_HTTPONLY = True(既安全又能保证Cookie正常传递) - 同步开
CSRF_COOKIE_SECURE = True(和SESSION的配置保持一致) - 加上这俩关键配置,让Django识别Nginx转发的真实请求:
USE_X_FORWARDED_HOST = True SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
示例配置片段:
# settings.py SESSION_COOKIE_DOMAIN = "your-domain.com" # 替换成你的域名/EC2公网IP SESSION_COOKIE_SECURE = True SESSION_COOKIE_HTTPONLY = True CSRF_COOKIE_SECURE = True USE_X_FORWARDED_HOST = True SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
2. 检查Nginx的反向代理配置
确保Nginx正确传递Cookie和请求头,不然Django拿不到会话信息。给你个参考配置片段:
server { listen 443 ssl; server_name your-domain.com; # 这里放你的SSL证书配置... location / { proxy_pass http://127.0.0.1:8000; # 指向Django运行的端口 proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass_header Set-Cookie; # 确保Cookie能正常传递 proxy_http_version 1.1; proxy_set_header Connection ""; } }
如果生产环境暂时用HTTP(不推荐),记得把SESSION_COOKIE_SECURE改成False,同时Nginx里的X-Forwarded-Proto设为http。
3. 核对Django中间件顺序
AuthenticationMiddleware必须放在SessionMiddleware之后,不然会话先处理不了,用户认证就会失效。检查settings.py里的MIDDLEWARE顺序:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', # 先处理会话 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # 再处理认证 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
4. 确认自定义用户模型的配置
必须在settings.py里指定你的自定义用户模型,不然Django会用默认的User模型,导致会话里的用户ID匹配不上:
AUTH_USER_MODEL = 'yourapp.CustomUser' # 替换成你的app名+模型名
5. 解决@login_required失效的特殊情况
既然LoginRequiredMixin能用,说明会话本身是有效的,可能是函数视图的装饰器没正确处理请求。可以在其他视图里手动通过会话拿用户试试:
from django.contrib.auth import get_user_model def your_protected_view(request): user_id = request.session.get('_auth_user_id') User = get_user_model() if user_id: request.user = User.objects.get(pk=user_id) # 后续业务逻辑
如果这样能拿到用户,说明AuthenticationMiddleware没正确处理请求,回到前面的中间件顺序或Nginx配置排查。
6. 排查缓存问题
登录视图加了@never_cache,但其他视图可能被缓存了,导致用户信息没更新。给需要用户认证的函数视图也加上@never_cache:
from django.views.decorators.cache import never_cache from django.contrib.auth.decorators import login_required @never_cache @login_required def protected_view(request): # 视图逻辑
内容的提问来源于stack exchange,提问作者Damian
相关产品推荐
相关产品推荐

