पायथन के लिए फ्लास्क का उपयोग करने वाले आगंतुकों का आईपी पता प्राप्त करें


220

मैं एक वेबसाइट बना रहा हूँ जहाँ उपयोगकर्ता लॉग ऑन कर सकते हैं और फाइलें डाउनलोड कर सकते हैं, फ्लास्क माइक्रो-फ्रेमवर्क ( वर्कर्ज़ग पर आधारित ) का उपयोग करके जो पायथन (मेरे मामले में 2.6) का उपयोग करता है।

जब वे लॉग ऑन करते हैं तो मुझे उपयोगकर्ताओं का आईपी पता प्राप्त करने की आवश्यकता होती है (लॉगिंग उद्देश्यों के लिए)। क्या किसी को भी यह करना आता है? निश्चित रूप से पायथन के साथ ऐसा करने का एक तरीका है?

जवाबों:


295

अनुरोध ऑब्जेक्ट तक पहुंचने के लिए दस्तावेज़ीकरण देखें और फिर इसी अनुरोध ऑब्जेक्ट, विशेषता से प्राप्त करें 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]
जोनाथन

46
के रूप में nginx के लिए, यह असली आईपी पते भेजता है HTTP_X_FORWARDED_FORताकि सुनिश्चित करें कि आप प्रत्येक अनुरोध के लिए localhost के साथ समाप्त नहीं करते हैं।
रस्मी ट्यूरेक

95

यदि आप एक का उपयोग कर रहे हैं , तो प्रॉक्सी इसे थोड़ा मुश्किल बना सकता है, ProxyFix ( फ्लास्क डॉक्स ) की जांच करना सुनिश्चित करें । request.environअपने विशेष वातावरण पर एक नज़र डालें । नग्नेक्स के साथ मैं कभी-कभी कुछ ऐसा करूंगा:

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

जब समीपता, जैसे कि nginx, आगे के पते, वे आम तौर पर अनुरोध हेडर में कहीं मूल आईपी को शामिल करते हैं।

अद्यतन फ्लास्क-सुरक्षा कार्यान्वयन देखें । फिर से, लागू करने से पहले ProxyFix के बारे में दस्तावेज की समीक्षा करें। आपका समाधान आपके विशेष वातावरण के आधार पर भिन्न हो सकता है।


2
यह तब काम करता है जब आप अपने रिवर्स प्रॉक्सी के कॉन्फ़िगरेशन में उपयुक्त फ़ील्ड सेट करते हैं। उत्पादन में उपयोग किया जाता है।
dnnrr

3
@drahnr हाँ वास्तव में। उपरोक्त कोड काम करता है यदि उदा। आपके द्वारा सेट किया गया उदाहरण: प्रॉक्सी_सेट_हीडर एक्स-रियल-आईपी $ रिमोट_एडआर;
पोर्स

@pors - यह काम करता है। मैं अपने nginx में आप के रूप में एक ही सेटिंग है। लेकिन मुझे अभी भी समझ नहीं आया कि कोड: request.headers.get ('X-Real-IP', request.remote_addr) काम क्यों नहीं करता है। ध्यान दें, सहजता से मुझे हेडर से मान मिलेगा और 'एक्स-रियल-आईपी' नाम का उपयोग करना होगा, क्योंकि मेरा नग्नेक्स आत्मविश्वास कैसा है।
लॉडर्जे

82

वास्तव में, आप जो पाएंगे, वह यह है कि बस निम्नलिखित प्राप्त करने पर आपको सर्वर का पता मिलेगा:

request.remote_addr

यदि आप क्लाइंट का IP पता चाहते हैं, तो निम्नलिखित का उपयोग करें:

request.environ['REMOTE_ADDR']

4
केवल अगर आप एक रिवर्स प्रॉक्सी के पीछे हैं, नहीं?
Ry-

3
@ मिनिटेक मैं कहूंगा कि आपके कोड को परवाह नहीं करनी चाहिए कि आप एक प्रॉक्सी के पीछे हैं या नहीं। यदि यह विकल्प रिवर्स प्रॉक्सी के बिना विश्वसनीय तरीके से काम करता है और दूसरा मानता है कि आप रिवर्स प्रॉक्सी के पीछे नहीं हैं, तो इसे प्राथमिकता दी जानी चाहिए। (यदि मैं आसानी से रिवर्स प्रॉक्सी सेट कर सकता हूं, तो मैं इसका परीक्षण करूंगा, लेकिन इस समय मेरे पास इससे अधिक समय लगेगा।)
jpmc26

@ jpmc26: मुझे कोई कारण नहीं दिखाई देता है कि इसे क्यों काम करना चाहिए। request.remote_addrएक संपत्ति की तरह लगता है कि रिवर्स प्रॉक्सी पर भरोसा किया जाता है या नहीं इसके आधार पर एक दूरस्थ पता मिलना चाहिए।
Ry-

3
Mod_wsgi का उपयोग करके, request.remote_addr हर बार सर्वर का पता लौटाता है। request.environ ['REMOTE_ADDR'] ने मुझे क्लाइंट का सार्वजनिक आईपी पता प्राप्त किया। शायद मुझे कुछ याद आ रहा है?
चिदो

@ jpmc26 यदि आपको दूरस्थ प्रॉक्सी के पीछे होने पर आपको अक्सर देखभाल करने की आवश्यकता होती है। यदि आप हैं, तो आप से कनेक्ट होने वाला IP रिमोट प्रॉक्सी सर्वर का होगा, और आपको मूल क्लाइंट IP प्राप्त करने के लिए जोड़े जाने वाले हेडर पर निर्भर रहना होगा। यदि आप नहीं हैं , तो वे हेडर आम तौर पर मौजूद नहीं होंगे, और आप कनेक्शन आईपी का उपयोग क्लाइंट आईपी के रूप में करना चाहते हैं। और आप आवश्यक रूप से हेडर के लिए जाँच नहीं कर सकते हैं और कनेक्शन आईपी पर वापस गिर सकते हैं यदि यह मौजूद नहीं है, क्योंकि तब यदि आप एक रिवर्स प्रॉक्सी के पीछे नहीं हैं तो एक क्लाइंट उनके आईपी को खराब कर सकता है, जो कई परिस्थितियों में एक सुरक्षा मुद्दा होगा। ।
मार्क एमी

28

उपयोगकर्ता के आईपी पते को निम्नलिखित स्निपेट का उपयोग करके पुनर्प्राप्त किया जा सकता है:

from flask import request
print(request.remote_addr)

3
यह सच नहीं है, अगर ऐप nginx जैसे प्रॉक्सी सर्वर के पीछे चल रहा है । जो यह अक्सर उत्पादन में होता है।
डेटशमैन

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

@ तीर्थ-आर समाधान ने मेरे लिए काम किया

#!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

नीचे दिया गया कोड हमेशा क्लाइंट का सार्वजनिक आईपी देता है (और प्रॉक्सी के पीछे निजी आईपी नहीं)।

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 config को बदलने के साथ इस उत्तर ने मेरे लिए काम किया। calvin.me/forward-ip-addresses-when-use-nginx-proxy
Romano Vacca


3

यदि आप अन्य बैलेंसर के पीछे Nginx का उपयोग करते हैं, उदाहरण के लिए AWS एप्लिकेशन बैलेंसर, 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

यह काम करना चाहिए। यह क्लाइंट आईपी एड्रेस (रिमोट होस्ट) प्रदान करता है।

ध्यान दें कि यह कोड सर्वर साइड पर चल रहा है।

from mod_python import apache

req.get_remote_host(apache.REMOTE_NOLOOKUP)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.