在Google App Engine标准环境下使用Flask结合ProxyFix获取用户真实IP地址
解决GAE环境下Flask request.remote_addr返回错误IP的问题
当然可以搞定这个问题!你遇到的情况是因为ProxyFix的默认配置没有适配Google App Engine的代理层级,咱们调整一下参数就能拿到正确的用户IP了。
问题根源
GAE标准环境的请求会经过多层内部代理,X-Forwarded-For请求头里的第一个值才是用户的真实IP,而后面跟着的是GAE内部代理的IP(比如你看到的169.254.1.1)。默认的ProxyFix只信任1层代理,所以它只会把最后一个代理的IP(也就是169.254.1.1)设为remote_addr,而不是取X-Forwarded-For里的第一个真实IP。
解决方案:调整ProxyFix的x_for参数
只需要给ProxyFix传入x_for=1参数,告诉它信任前面1层代理的X-Forwarded-For头,这样它就会从这个头里提取最靠前的真实用户IP,替换掉remote_addr的值。
修改后的代码如下(注意中间件的顺序:先处理代理,再处理Cloud NDB):
from flask import Flask, request from werkzeug.middleware.proxy_fix import ProxyFix from google.cloud.ndb import ndb_wsgi_middleware app = Flask(__name__) # 先应用ProxyFix,调整IP获取逻辑 app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1) # 再应用ndb中间件 app.wsgi_app = ndb_wsgi_middleware(app.wsgi_app) # 测试用接口,验证IP是否正确 @app.route('/') def check_ip(): return f"Your real IP: {request.remote_addr}"
为什么这样有效?
x_for=1表示ProxyFix会跳过1层代理的IP,直接使用X-Forwarded-For列表中的第一个IP作为remote_addr。- 中间件顺序很重要:必须让
ProxyFix先处理请求,把正确的IP注入到request对象中,之后ndb_wsgi_middleware再处理其他逻辑,这样后续代码里的request.remote_addr才会是正确的用户IP。
另外放心,在GAE环境中X-Forwarded-For头是安全可靠的——GAE会过滤掉用户自己发送的这个头,只会保留真实的代理链路信息,不用担心伪造的问题。
内容的提问来源于stack exchange,提问作者minou
相关产品推荐
相关产品推荐

