Nat*_*ova 13 python x-forwarded-for starlette fastapi
我在 FastAPI 上有一个 API,当他请求我的页面时,我需要获取客户端的真实 IP 地址。
我很乐意使用starlette Request。但它返回我的服务器 IP,而不是客户端远程 IP。
我的代码:
@app.post('/my-endpoint')
async def my_endpoint(stats: Stats, request: Request):
ip = request.client.host
print(ip)
return {'status': 1, 'message': 'ok'}
Run Code Online (Sandbox Code Playgroud)
我在做什么错?如何获得真实IP(如在Flask request.remote_addr 中)?
har*_*lee 32
FastAPI using-request-directly文档页面显示了以下示例:
from fastapi import FastAPI, Request
app = FastAPI()
@app.get("/items/{item_id}")
def read_root(item_id: str, request: Request):
client_host = request.client.host
return {"client_host": client_host, "item_id": item_id}
Run Code Online (Sandbox Code Playgroud)
有了这个例子,我就可以节省十分钟的时间来思考Starlette 的 Request 类
Hed*_*ide 19
request.client应该可以工作,除非您在代理(例如 nginx)后面运行,在这种情况下使用 uvicorn 的--proxy-headers标志来接受这些传入的标头并确保代理转发它们。
Rco*_*rNY 16
你不需要设置--proxy-headersbc 它默认是启用的,但它只信任--forwarded-allow-ips默认的IP127.0.0.1
为了安全起见,您应该只信任来自反向代理 IP 的代理标头(而不是信任所有带有'*')。如果它在同一台机器上,那么默认值应该可以工作。虽然我从 nginx 日志中注意到它使用 ip6 与 uvicorn 通信,所以我必须使用 ip6,--forwarded-allow-ips='[::1]'然后我才能在 FastAPI 中看到 IP 地址。您还可以用来--forwarded-allow-ips='127.0.0.1,[::1]'捕获 localhost 上的 ip4 和 ip6。
--proxy-headers / --no-proxy-headers- 启用/禁用 X-Forwarded-Proto、X-Forwarded-For、X-Forwarded-Port 以填充远程地址信息。默认为启用,但仅限于仅信任转发允许 ips 配置中的连接 IP。
--forwarded-allow-ips- 以逗号分隔的 IP 列表,以信任代理标头。默认为 $FORWARDED_ALLOW_IPS 环境变量(如果可用)或“127.0.0.1”。通配符“*”表示始终信任。
参考:https: //www.uvicorn.org/settings/#http
小智 11
如果您使用 nginx 和 uvicorn\xef\xbc\x8c,则应设置proxy-headersuvicorn\xef\xbc\x8c,并且您的 nginx 配置应添加Host\xe3\x80\x81X-Real-IP和X-Forwarded-For.
\ne.g.
server {\n # the port your site will be served on\n listen 80;\n # the domain name it will serve for\n server_name <your_host_name>; # substitute your machine's IP address or FQDN\n\n# add_header Access-Control-Allow-Origin *;\n # add_header Access-Control-Allow-Credentials: true;\n add_header Access-Control-Allow-Headers Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE;\n add_header access-control-allow-headers authorization;\n # Finally, send all non-media requests to the Django server.\n location / {\n proxy_pass http://127.0.0.1:8000/; # the uvicorn server address\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n }\n}\n\nRun Code Online (Sandbox Code Playgroud)\n在 nginx 文档上:
\nThis middleware can be applied to add HTTP proxy support to an\napplication that was not designed with HTTP proxies in mind. It\nsets REMOTE_ADDR, HTTP_HOST from X-Forwarded headers. While\nWerkzeug-based applications already can use\n:py:func:werkzeug.wsgi.get_host to retrieve the current host even if\nbehind proxy setups, this middleware can be used for applications which\naccess the WSGI environment directly\xe3\x80\x82\nIf you have more than one proxy server in front of your app, set\nnum_proxies accordingly.\nDo not use this middleware in non-proxy setups for security reasons.\nThe original values of REMOTE_ADDR and HTTP_HOST are stored in\nthe WSGI environment as werkzeug.proxy_fix.orig_remote_addr and\nwerkzeug.proxy_fix.orig_http_host\n:param app: the WSGI application\n:param num_proxies: the number of proxy servers in front of the app. \nRun Code Online (Sandbox Code Playgroud)\n
如果您已根据 @AllenRen 的答案正确配置了 nginx 配置,请尝试使用uvicorn 的--proxy-headers和标志。--forwarded-allow-ips='*'
| 归档时间: |
|
| 查看次数: |
8570 次 |
| 最近记录: |