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

在Flask-Nginx-Gunicorn架构中获取用户真实IP的问题求助

Flask获取用户真实IP失败的解决方案

在Flask应用中尝试获取用户真实IP时,始终只能拿到本地主机IP或服务器自身IP,无法获取用户实际IP。

已尝试的操作

  • 以下是尝试过的IP获取代码:
if request.headers.getlist("X-Forwarded-For"):
    client_ip = request.headers.getlist("X-Forwarded-For")[0]
else:
    client_ip = request.remote_addr
  • 尝试使用Werkzeug的ProxyFix中间件,但问题仍未解决。
  • 当前Nginx反向代理配置:
location / {
    proxy_pass ......;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_redirect off;
    proxy_read_timeout 300;
    proxy_connect_timeout 300;
    proxy_send_timeout 300; 
}

# Error pages
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;

location = /50x.html {
    root /usr/share/nginx/html;
}

# Deny access to hidden files and directories
location ~ /\. {
    deny all;
}

可行解决方案

1. 正确配置ProxyFix中间件

很多人使用ProxyFix时只导入但未正确挂载到Flask的WSGI应用上,导致失效。正确配置方式:

from flask import Flask
from werkzeug.middleware.proxy_fix import ProxyFix

app = Flask(__name__)
# 信任1层反向代理(Nginx),根据实际代理层数调整x_for参数
app.wsgi_app = ProxyFix(
    app.wsgi_app,
    x_for=1,  # 处理X-Forwarded-For
    x_proto=1,  # 处理X-Forwarded-Proto
    x_host=1  # 处理X-Forwarded-Host
)

2. 优化IP获取逻辑

X-Forwarded-For可能包含多层代理IP,最左侧为用户真实IP,但需过滤私有IP避免伪造:

from flask import request

def get_real_ip():
    x_forwarded_for = request.headers.get("X-Forwarded-For")
    if x_forwarded_for:
        # 分割IP列表并去除空格
        ip_list = [ip.strip() for ip in x_forwarded_for.split(",")]
        # 过滤私有IP段
        private_ips = ("127.", "192.168.", "10.", "172.16.", "172.31.")
        for ip in ip_list:
            if not ip.startswith(private_ips):
                return ip
    # fallback到remote_addr
    return request.remote_addr

3. 验证Nginx配置并重启

  • 确认proxy_pass指向正确的Flask服务地址(例如http://127.0.0.1:5000),无拼写错误。
  • 确保proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;在location /块内且未被注释。
  • 执行命令重启Nginx使配置生效:
sudo systemctl restart nginx

4. 测试验证

添加测试接口验证IP获取结果:

@app.route("/check_ip")
def check_ip():
    return f"你的真实IP:{get_real_ip()}"

使用外部网络访问该接口,确认返回IP与实际公网IP一致。

内容的提问来源于stack exchange,提问作者Kareem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 04:20:20