FastAPI (starlette) получить реальный IP клиента

У меня есть API на FastAPI, и мне нужно получить реальный 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'}

Что я делаю не так? Как получить настоящий IP (как во Flask request.remote_addr)?


person Nataly Firstova    schedule 06.02.2020    source источник


Ответы (4)


request.client должен работать, если вы не работаете за прокси (например, nginx), в этом случае используйте флаг --proxy-headers uvicorn, чтобы принимать эти входящие заголовки и убедиться, что прокси пересылает их.

person Hedde van der Heide    schedule 07.02.2020

если вы используете nginx и uvicorn ,, вы должны установить proxy-headers для uvicorn ,, и ваша конфигурация nginx должна быть добавлена ​​_2 _ 、 _ 3_ и `X-Forwarded-For`.
например,

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;
    }
}

в документе nginx:

This middleware can be applied to add HTTP proxy support to an
application that was not designed with HTTP proxies in mind. It
sets REMOTE_ADDR, HTTP_HOST from X-Forwarded headers. While
Werkzeug-based applications already can use
:py:func:werkzeug.wsgi.get_host to retrieve the current host even if
behind proxy setups, this middleware can be used for applications which
access the WSGI environment directly。
If you have more than one proxy server in front of your app, set
num_proxies accordingly.
Do not use this middleware in non-proxy setups for security reasons.
The original values of REMOTE_ADDR and HTTP_HOST are stored in
the WSGI environment as werkzeug.proxy_fix.orig_remote_addr and
werkzeug.proxy_fix.orig_http_host
:param app: the WSGI application
:param num_proxies: the number of proxy servers in front of the app.  
person AllenRen    schedule 17.11.2020
comment
восходящий uvicorn {сервер unix: /tmp/uvicorn.sock; } Разве мы не добавляем это? Это в документации - person Himal Acharya; 10.01.2021

На странице документации FastAPI using-request-direct показан этот пример:

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}

Имея этот пример, я бы сэкономил десять минут на размышлениях с классом Starlette's Request.

person harrolee    schedule 02.02.2021

Если вы правильно настроили конфигурацию nginx на основе ответа @AllenRen, попробуйте использовать --proxy-headers, а также --forwarded-allow-ips='*' флаги для uvicorn.

person Ali AzG    schedule 30.11.2020