Flask for Pythonを使用して訪問者のIPアドレスを取得する


220

Pythonを使用する(Werkzeugに基づく)Flaskマイクロフレームワーク(私の場合は2.6)を使用して、ユーザーがログオンしてファイルをダウンロードできるWebサイトを作成しています。

ユーザーがログオンするときに(ログの目的で)ユーザーのIPアドレスを取得する必要があります。誰でもこれを行う方法を知っていますか?確かにPythonでそれを行う方法はありますか?

回答:


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

46
nginxに関しては、実際のIPアドレスを送信するHTTP_X_FORWARDED_FORので、リクエストごとにlocalhostになっていないことを確認してください。
Rasty Turek、2014

95

プロキシはこれを少しトリッキーにする可能性があります。使用している場合は必ずProxyFixFlask docs)をチェックしてください。request.environ特定の環境で見てください。nginxでは、私は時々このようなことをします:

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

nginxなどのプロキシがアドレスを転送する場合、通常、リクエストヘッダーのどこかに元のIPが含まれます。

更新 フラスコのセキュリティの実装を参照してください。ここでも、実装する前にProxyFixに関するドキュメントを確認してください。ソリューションは、特定の環境によって異なる場合があります。


2
これは、リバースプロキシの構成で適切なフィールドを設定すると機能します。生産で使用されます。
drahnr 2015

3
@drahnrはい、確かに。上記のコードは、たとえばnginxで次のように設定した場合に機能します。proxy_set_header X-Real-IP $ remote_addr;
pors

@pors-機能します。私と同じnginx confの設定があります。しかし、コードrequest.headers.get( 'X-Real-IP'、request.remote_addr)が機能しない理由はまだわかりません。直感的には、ヘッダーから値を取得し、「X-Real-IP」という名前を使用することに注意してください。これは、nginx confがどのように使用されるかです。
lostdorje

82

実際、あなたが見つけるのは、単に以下を取得すると、サーバーのアドレスが取得されるということです。

request.remote_addr

クライアントのIPアドレスが必要な場合は、以下を使用します。

request.environ['REMOTE_ADDR']

4
リバースプロキシの背後にいる場合のみ、そうではありませんか?
Ry-

3
@minitech私はあなたのコードはあなたがプロキシの後ろにいるかどうかを気にするべきではないと言います。このオプションがリバースプロキシに関係なく確実に機能し、他のオプションがリバースプロキシの背後にいないことを想定している場合は、これが推奨されます。(リバースプロキシを簡単にセットアップできる場合は、これをテストしますが、現時点では時間がかかります。)
jpmc26

@ jpmc26:まったく機能する理由はわかりません。request.remote_addrリバースプロキシが信頼されているかどうかによって、リモートアドレスを取得する必要があるプロパティのように聞こえます。
Ry-

3
mod_wsgiを使用して、request.remote_addrは毎回サーバーアドレスを返しました。request.environ ['REMOTE_ADDR']は、クライアントのパブリックIPアドレスを取得しました。多分私は何かが足りないのですか?
Chiedo 2014

@ jpmc26 リモートプロキシの背後にいる場合は、注意必要です。接続している場合、接続先のIPはリモートプロキシサーバーのものであり、元のクライアントIPを取得するために追加するヘッダーに依存する必要があります。そうでない場合、これらのヘッダーは通常存在せず、クライアントIPとして接続IPを使用する必要があります。そして、必ずしもヘッダーを確認し、存在しない場合は接続IPにフォールバックできるとは限りません。リバースプロキシの背後にいない場合、クライアントはIPを偽装する可能性があるため、多くの状況でセキュリティの問題になります。 。
Mark Amery

28

ユーザーのIPアドレスは、次のスニペットを使用して取得できます。

from flask import request
print(request.remote_addr)

3
これは、アプリがnginxなどのプロキシサーバーの背後で実行されている場合は当てはまりません。どれが生産中か。
datashaman 2017

17

私はNginxNginx Config以下を持っています:

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-when-using-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.