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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 15:25:44