客至汲泉烹茶, 抚琴听者知音

fastapi获取访客真实ip

最近一时兴起想好好搞一下我的 API 项目,用的自然是 python 的 fastapi 库。没做几个 API 就想到个问题:我怎么知道我的 API 有没有人用?解决方案当然就是统计一下 API 调用次数啦。网上搜了一下貌似没有 fastapi 简单可行的统计方案,没办法只能自己写了。那么首先我需要知道访客的 ip,这样相当于有个 key,也可以大致了解调用情况。去 fastapi 文档上查了一下,有相关代码!

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}

赶紧复制到 python 里试试效果,没想到,它给我返回 127.0.0.1?我想让它给我返回用户的真实 ip 而不是 本地 ip 啊。想必部署到服务器上显示的也是服务端的 ip 吧,试了一下果然如此。

那没办法了,万事不决求助 Google。很快在 Stack Overflow 上找到了类似的提问,整合了一下几个回答,终于摸索出了解决方案。具体来说分为三步:

首先使用 nginx 进行反代,因为我这个项目本身就是用的 nginx 所以这一步跳过。

然后修改 nginx 的配置文件如下:

server {
  # the port your site will be served on
    listen 80;
  # the domain name it will serve for
    server_name <your_host_name>; # substitute your machine's IP address or FQDN

#    add_header Access-Control-Allow-Origin *;
    # add_header Access-Control-Allow-Credentials: true;
    add_header Access-Control-Allow-Headers Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE;
    add_header access-control-allow-headers authorization;
    # Finally, send all non-media requests to the Django server.
    location / {
        proxy_pass http://127.0.0.1:8000/; # the uvicorn server address
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
}
本人小白,只会用宝塔,同样用宝塔的同学可以在反向代理中找到配置文件,不过宝塔的反代貌似不用做任何修改。反正我是这一步也跳过了。

最后,也是最重要的一步,使用 uvicorn 启动服务,但是要加上 --proxy-headers --forwarded-allow-ips='*',也即:

uvicorn main:app --host 0.0.0.0 --port 8000 --proxy-headers --forwarded-allow-ips='*'

这样就可以成功获取访客 ip 啦。但是测试下来,我另外一个网站调用的这个 API,打开网站时日志输出的是我电脑的 ip,而非网站服务器的 ip,目前仍然不知道解决方案……

添加新评论