跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

Python Flask怎么获取客户端IP_Nginx反向代理情况下的HTTP_X_FORWARDED_FOR真实IP获取

Flask中request.remote_addr总为127.0.0.1是因Nginx反向代理导致,真实IP需通过可信代理透传的X-Forwarded-For头获取,且必须校验remote_addr是否在可信代理列表中才信任该头,推荐使用werkzeug.middleware.proxy_fix.ProxyFix中间件并显式配置trusted_proxies。 Flask里request.remote_addr为什么总是127.0.0.1 因为Nginx做了反向代理,Flask看到的TCP连接来源是Nginx本机,不是原始客户端。直接读
request.remote_addr
拿到的是Nginx的IP,不是用户真实IP。 必须依赖Nginx透传的HTTP头,最常用的是
X-Forwarded-For
。但不能无条件信任——这个头可被客户端伪造,必须只从可信代理(比如你自己的Nginx)后面才取它。 Nginx配置里要加
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
,否则Flask根本收不到这个头 Flask默认不解析
X-Forwarded-For
,得自己写逻辑提取 如果Nginx和Flask之间还有其他代理(比如CDN、负载均衡),
X-Forwarded-For
可能含多个IP,用逗号分隔,最左边才是用户真实IP(前提是链路可信) 怎么安全地从X-Forwarded-For取真实IP 不能直接
request.headers.get("X-Forwarded-For", "").split(",")[0].strip()
——这等于把伪造的头当真了。必须先确认请求确实来自可信代理。 推荐做法:把你的Nginx服务器IP(或网段)设为“可信代理列表”,只在
request.remote_addr
属于该列表时,才信任
X-Forwarded-For
。 立即学习 “ Python免费学习笔记(深入) ”; Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 用Flask内置的
request.environ.get("HTTP_X_FORWARDED_FOR")
比
request.headers.get()
更可靠(某些WSGI服务器会把头转成
HTTP_*
环境变量) 真实IP取法:
ip_list = [ip.strip() for ip in (x_forwarded_for or "").split(",")]
,然后取
ip_list[0]
,但仅当
request.remote_addr
在可信列表中 别忘了处理空值、格式错误(比如
" , 1.2.3.4, "
)和IPv6压缩格式 Flask有没有现成方案?TrustProxyMiddleware靠谱吗 Flask本身不提供自动信任代理逻辑,但可以用
werkzeug.middleware.proxy_fix.ProxyFix
——它就是干这个的,但要注意版本和配置。 关键点:它不会“自动猜”哪些IP可信,必须显式指定
trusted_hosts
或
trusted_proxies
(v2.2+改名了)。 v2.2+用法:
app.wsgi_app = ProxyFix(app.wsgi_app, trusted_proxies=["127.0.0.1", "10.0.0.0/8"])
旧版(trusted_hosts参数,但只支持域名/主机名,不支持IP段,慎用 启用后,
request.remote_addr
会自动变成
X-Forwarded-For
里的第一个IP——但前提是请求真从你列的那些IP来,否则会被忽略 别在开发环境开这个,本地调试时
remote_addr
是
127.0.0.1
,一开就全变错 为什么有时候拿到的是::1或者空字符串
::1
是IPv6下的localhost,说明Nginx没正确传
X-Forwarded-For
,或者Flask收到的
remote_addr
是
::1
,但
ProxyFix
没把它列进
trusted_proxies
(IPv6地址要写成
::1
,不是
127.0.0.1
)。 空字符串常见于:Nginx配置漏了
proxy_set_header
、用了
fastcgi
协议但没配对应头、或者WSGI服务器(如Gunicorn)禁用了环境变量透传。 检查Nginx access log,确认
$http_x_forwarded_for
字段有值 在Flask里打印
request.environ
,搜
HTTP_X_FORWARDED_FOR
是否存在 如果用Gunicorn,确保没加
--no-env
,且没在
gunicorn.conf.py
里清空
env
字段 信任链断在哪,真实IP就丢在哪。Nginx配错一行,Flask里写十行逻辑也救不回来。

相关文章