Flask for Python을 사용하여 방문자의 IP 주소 가져 오기


220

파이썬 (제 경우 2.6)을 사용 하는 Flask 마이크로 프레임 워크 ( Werkzeug 기반 )를 사용 하여 사용자가 로그온하고 파일을 다운로드 할 수있는 웹 사이트를 만들고 있습니다 .

로그온 할 때 (로깅 목적으로) 사용자의 IP 주소를 가져와야합니다. 누구든지 이것을하는 방법을 알고 있습니까? 분명히 파이썬으로 할 수있는 방법이 있습니까?

답변:


295

Request 오브젝트에 액세스하는 방법에 대한 문서를 참조한 다음 동일한 동일한 Request 오브젝트 인 속성을 가져 오십시오 remote_addr.

코드 예

from flask import request
from flask import jsonify

@app.route("/get_my_ip", methods=["GET"])
def get_my_ip():
    return jsonify({'ip': request.remote_addr}), 200

자세한 내용은 Werkzeug 설명서를 참조하십시오 .


1
언젠가, 그것은 유용 할 수 있습니다 : request.access_route [0]
조나단 Prates

46
nginx의 경우 실제 IP 주소를 보내 HTTP_X_FORWARDED_FOR므로 각 요청에 대해 localhost로 끝나지 않도록하십시오.
Rasty Turek

95

프록시는 이것을 약간 까다로울 수 있습니다. ProxyFix ( Flask docs )를 사용 하고 있는지 확인하십시오 . request.environ특정 환경에서 살펴보십시오 . nginx를 사용하면 때로는 다음과 같은 작업을 수행합니다.

from flask import request   
request.environ.get('HTTP_X_REAL_IP', request.remote_addr)   

nginx와 같은 프록시가 주소를 전달하면 일반적으로 요청 헤더 어딘가에 원래 IP가 포함됩니다.

업데이트 플라스크 보안 구현을 참조하십시오 . 다시 구현하기 전에 ProxyFix에 대한 문서를 검토하십시오. 솔루션은 특정 환경에 따라 다를 수 있습니다.


2
리버스 프록시 구성에서 적절한 필드를 설정할 때 작동합니다. 생산에 사용됩니다.
drahnr

3
@drahnr 그렇습니다. 위 코드는 예를 들어 nginx에서 설정 한 경우 작동합니다. proxy_set_header X-Real-IP $ remote_addr;
pors

@ pors-작동합니다. 내 nginx conf의 설정과 동일한 설정이 있습니다. 그러나 여전히 코드 : request.headers.get ( 'X-Real-IP', request.remote_addr)이 작동하지 않는 이유를 이해하지 못합니다. 직관적으로 헤더에서 값을 가져 와서 nginx conf와 같은 이름으로 'X-Real-IP'라는 이름을 사용합니다.
lostdorje

82

실제로, 당신은 단순히 다음을 얻을 때 서버의 주소를 얻을 것입니다 찾을 수 있습니다 :

request.remote_addr

클라이언트 IP 주소를 원하면 다음을 사용하십시오.

request.environ['REMOTE_ADDR']

4
리버스 프록시 뒤에있는 경우에만
Ry-

3
@minitech 나는 당신의 코드가 프록시 뒤에 있는지 여부를 신경 쓰지 않아야한다고 말하고 싶습니다. 이 옵션이 리버스 프록시와 상관없이 안정적으로 작동하고 다른 옵션이 리버스 프록시 뒤에 있지 않다고 가정하는 경우이 옵션이 선호됩니다. (
리워드

@ jpmc26 : 왜 작동 해야하는지 이유가 없습니다. request.remote_addr리버스 프록시의 신뢰 여부에 따라 원격 주소를 가져와야하는 속성처럼 들립니다.
Ry-

3
mod_wsgi를 사용하여 request.remote_addr은 매번 서버 주소를 반환했습니다. request.environ [ 'REMOTE_ADDR']이 (가) 고객의 공개 IP 주소를 얻었습니다. 어쩌면 내가 뭔가를 놓치고 있습니까?
Chiedo

@ jpmc26 당신은 자주 원격 프록시 뒤에 있다면 신경 쓸 필요가있다. 연결되어있는 경우 연결하는 IP보다 원격 프록시 서버에 속하며 원래 클라이언트 IP를 가져 오려면 추가 한 헤더를 사용해야합니다. 이 아닌 경우 일반적으로 해당 헤더가 존재하지 않으며 연결 IP를 클라이언트 IP로 사용하려고합니다. 또한 헤더를 확인하고 연결 IP가없는 경우 연결 IP로 폴백 할 수는 없습니다 . 역방향 프록시를 사용 하지 않는 경우 클라이언트가 IP를 스푸핑 할 수 있기 때문에 많은 경우 보안 문제가 발생할 수 있습니다. .
Mark Amery

28

다음 스 니펫을 사용하여 사용자의 IP 주소를 검색 할 수 있습니다.

from flask import request
print(request.remote_addr)

3
앱이 nginx 와 같은 프록시 서버 뒤에서 실행되는 경우에는 사실이 아닙니다 . 그것은 종종 생산에 있습니다.
datashaman

17

나는이 Nginx에 아래와로를 Nginx의 구성 :

server {
    listen 80;
    server_name xxxxxx;
    location / {
               proxy_set_header   Host                 $host;
               proxy_set_header   X-Real-IP            $remote_addr;
               proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
               proxy_set_header   X-Forwarded-Proto    $scheme;

               proxy_pass http://x.x.x.x:8000;
        }
}

@ tirtha-r 솔루션이 나를 위해 일했습니다.

#!flask/bin/python
from flask import Flask, jsonify, request
app = Flask(__name__)

@app.route('/', methods=['GET'])
def get_tasks():
    if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
        return jsonify({'ip': request.environ['REMOTE_ADDR']}), 200
    else:
        return jsonify({'ip': request.environ['HTTP_X_FORWARDED_FOR']}), 200

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0', port=8000)

나의 요청과 응답 :

curl -X GET http://test.api

{
    "ip": "Client Ip......"
}

13

아래 코드는 항상 클라이언트의 퍼블릭 IP를 제공합니다 (프록시 뒤의 프라이빗 IP는 아님).

from flask import request

if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
    print(request.environ['REMOTE_ADDR'])
else:
    print(request.environ['HTTP_X_FORWARDED_FOR']) # if behind a proxy

이 답변은이 블로그에 따라 내 nginx 구성을 변경하는 것과 함께 나를 위해 일했습니다. calvin.me/forward-ip-addresses-nginx-proxy 사용시
Romano Vacca

7

httpbin.org 는 다음 방법을 사용합니다.

return jsonify(origin=request.headers.get('X-Forwarded-For', request.remote_addr))

127.0.0.1프록시로 인한 반품은 별로 도움이되지 않습니다.
Uri Goren

3

다른 밸런서 (예 : AWS Application Balancer) 뒤에 Nginx를 사용하는 경우 HTTP_X_FORWARDED_FOR은 주소 목록을 반환합니다. 다음과 같이 수정 될 수 있습니다.

if 'X-Forwarded-For' in request.headers:
    proxy_data = request.headers['X-Forwarded-For']
    ip_list = proxy_data.split(',')
    user_ip = ip_list[0]  # first address in list is User IP
else:
    user_ip = request.remote_addr  # For local development


0

이 작업을 수행해야합니다. 클라이언트 IP 주소 (원격 호스트)를 제공합니다.

이 코드는 서버 측에서 실행되고 있습니다.

from mod_python import apache

req.get_remote_host(apache.REMOTE_NOLOOKUP)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.