Nginx反向代理下Django Admin登录失败及重定向问题求助
Django Admin 反向代理下的登录问题及解决方法
我遇到了和五年前Stack Overflow上某提问几乎一致的Django Admin登录问题,始终没找到明确解决方案。当前环境是Nginx监听80端口,将所有以prefix开头的URL反向代理到Django监听的8000端口,初始配置如下:
location /prefix/ { proxy_pass http://0.0.0.0:8000/; }
出现的问题
- 访问
/prefix/admin/时返回302重定向至/admin/login/?next=/admin/,但直接访问/prefix/admin/login能正常显示登录页面 - 在
/admin/login/页面提交账号密码后出现404错误
之前的尝试
第一个问题曾用以下配置临时解决:
location /prefix/admin/ { proxy_pass http://0.0.0.0:8000/admin/login/; }
但尝试解决第二个问题时,用下面的配置出现了过多重定向:
location = /admin/login { proxy_pass http://0.0.0.0:8000/admin/; }
补充日志对比:本地登录时,POST请求后GET /admin/返回200;远程环境中该GET请求返回302。
正确解决方案
核心问题在于Django没有正确识别反向代理后的URL前缀,导致生成的重定向路径、表单提交URL缺失prefix。需要从Nginx和Django两端同时配置:
1. 修正Nginx反向代理配置
在反向代理块中添加必要的HTTP头部,传递真实的请求信息给Django:
location /prefix/ { proxy_pass http://0.0.0.0:8000/; # 传递真实请求的协议、主机和前缀 proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Prefix /prefix; proxy_set_header X-Forwarded-For $remote_addr; }
2. 配置Django的settings.py
在Django配置文件中添加以下设置,让系统识别反向代理的前缀:
# 允许的主机域名,根据实际情况修改 ALLOWED_HOSTS = ['your-domain.com'] # 启用反向代理头部处理 USE_X_FORWARDED_HOST = True # 如果使用HTTPS,保留下面一行;否则可注释 SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # 设置URL前缀,让Django生成的所有URL自动带上/prefix FORCE_SCRIPT_NAME = '/prefix' # 修正静态文件和媒体文件的URL前缀 STATIC_URL = '/prefix/static/' MEDIA_URL = '/prefix/media/'
原理说明
- Nginx通过
X-Forwarded-*头部将真实的请求上下文传递给Django,避免Django生成不带prefix的错误URL FORCE_SCRIPT_NAME让Django明确自己运行在/prefix路径下,Admin的登录重定向、表单提交路径都会自动带上该前缀- 无需单独为Admin路径设置特殊location规则,统一的反向代理配置即可处理所有请求
内容的提问来源于stack exchange,提问作者haojie
相关产品推荐
相关产品推荐

