Express.js: दूरस्थ क्लाइंट पता कैसे प्राप्त करें


256

मुझे पूरी तरह से समझ नहीं आ रहा है कि मुझे एक दूरस्थ उपयोगकर्ता का आईपी पता कैसे प्राप्त करना चाहिए।

मान लीजिए कि मेरे पास एक सरल अनुरोध मार्ग है जैसे:

app.get(/, function (req, res){
   var forwardedIpsStr = req.header('x-forwarded-for');
   var IP = '';

   if (forwardedIpsStr) {
      IP = forwardedIps = forwardedIpsStr.split(',')[0];  
   }
});

क्या वास्तविक उपयोगकर्ता IP पता प्राप्त करने के लिए उपरोक्त दृष्टिकोण सही है या कोई बेहतर तरीका है? और परदे के पीछे के बारे में क्या?


1
विवरण के अनुसार नोड-आईपीवेयर का उपयोग कैसे करें
un33k

अगर आप 'example.com' की तरह req.hostname नहीं पा सकते हैं: stackoverflow.com/a/37824880/5333284
zhi.yang

जवाबों:


469

यदि आप NGINX की तरह एक प्रॉक्सी के पीछे भाग रहे हैं या आपके पास क्या है, तभी आपको forward x-फॉरवर्डेड-फॉर ’के लिए जाँच करनी चाहिए:

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

यदि प्रॉक्सी 'आपकी' नहीं है, तो मैं 'x-फॉरवर्ड-फॉर' हेडर पर भरोसा नहीं करूंगा, क्योंकि यह स्पूफ हो सकता है।


2
यह सही है, हालांकि मेरी स्थिति में मुझे वर्ग कोष्ठक (ऊपर संपादित देखें) का उपयोग करना था, साथ ही यह भी सुनिश्चित करें कि आपके पास अपने nginx कॉन्फ़िगरेशन में x- अग्रेषित-सक्षम है। एक जादू की तरह काम करता है!
नौ सौ

43
आपको यह ध्यान रखने की आवश्यकता है कि आपको यह निर्देश proxy_set_header X-Forwarded-For $remote_addr;अपने nginx कॉन्फ़िगरेशन में डालना है, यदि आप अपने स्वयं के रिवर्स प्रॉक्सी का उपयोग कर रहे हैं।
कोकर

आप तो http (s) ब्राउज़र में आईपी उपयोग करना चाहते हैं: // [IPv6]: पोर्ट सूचना [] की जरूरत है, उम्मीद है कि इस मदद करता है
psuhas

43
कॉपी-पास्ता उपयोगकर्ता कृपया ध्यान दें: यह आईपी पते की अल्पविराम से अलग की गई सूची लौटा सकता है। हमारे पास एक dev से एक बग है जो इसे कॉपी करता है और परिणाम की तुलना IP से करता है। शायद var ip = (req.headers['x-forwarded-for'] || req.connection.remoteAddress || '').split(',')[0].trim();ग्राहक आईपी पाने के लिए कुछ करना पसंद करते हैं।
डेवी जोन्स

3
@ रिशव :: 1 स्थानीयहोस्ट के लिए आईपीवी 6 पता है
डैनियल ओ

238

जबकि @alessioalex से उत्तर काम करता है, वहाँ एक और तरीका है जैसा कि एक्सप्रेस के पीछे के भाग में व्यक्त किया गया है - गाइड

  1. app.set('trust proxy', true)अपने व्यक्त आरंभीकरण कोड में जोड़ें ।
  2. जब आप दूरस्थ क्लाइंट का आईपी प्राप्त करना चाहते हैं, तो सामान्य तरीके से उपयोग करें req.ipया req.ips(जैसे कि रिवर्स प्रॉक्सी नहीं है)

वैकल्पिक पढ़ने:

  • का प्रयोग करें req.ipया req.ipsreq.connection.remoteAddressइस समाधान के साथ काम नहीं करता है।
  • 'trust proxy'यदि आपको x-forwarded-forहेडर के माध्यम से पारित किए गए सब कुछ पर भरोसा करने की तुलना में अधिक परिष्कृत की आवश्यकता होती है, तो इसके लिए अधिक विकल्प उपलब्ध हैं (उदाहरण के लिए, जब आपका प्रॉक्सी प्री-सोर्सिंग एक्स-फॉरवर्ड किए गए-हेडर को अविश्वसनीय स्रोतों से नहीं हटाता है)। अधिक जानकारी के लिए लिंक की गई गाइड देखें।
  • यदि आपका प्रॉक्सी सर्वर x-forwarded-forहेडर को आबाद नहीं करता है , तो दो संभावनाएँ हैं।
    1. प्रॉक्सी सर्वर उस जानकारी को रिले नहीं करता है जहां अनुरोध मूल रूप से था। इस मामले में, यह पता लगाने का कोई तरीका नहीं होगा कि अनुरोध मूल रूप से कहां था। आपको पहले प्रॉक्सी सर्वर के कॉन्फ़िगरेशन को संशोधित करने की आवश्यकता है।
      • उदाहरण के लिए, यदि आप अपने रिवर्स प्रॉक्सी के रूप में nginx का उपयोग करते हैं, तो आपको proxy_set_header X-Forwarded-For $remote_addr;अपने कॉन्फ़िगरेशन में जोड़ना पड़ सकता है।
    2. प्रॉक्सी सर्वर उस जानकारी पर निर्भर करता है जहां अनुरोध मूल रूप से एक मालिकाना फैशन में था (उदाहरण के लिए, कस्टम http हेडर)। ऐसे मामले में, यह जवाब काम नहीं करेगा। उस जानकारी को प्राप्त करने के लिए एक कस्टम तरीका हो सकता है, लेकिन आपको पहले तंत्र को समझने की आवश्यकता है।

4
मेरा उत्तर सामान्य था (एक्सप्रेस से बंधा हुआ नहीं), लेकिन यदि आप एक्सप्रेस का उपयोग कर रहे हैं तो वास्तव में बेहतर तरीका है।
एलेसियोलेक्स

4
आपके प्रॉक्सी सर्वर को हेडर 'x-फॉरवर्डेड-फॉर' सेट को रिमोट एड्रेस पर रखना होगा। उदाहरण के लिए nginx के मामले में, आपके पास होनी चाहिए प्रॉक्सी_सेट_हीडर एक्स-फॉरवर्डेड-फॉर $ रिमोट_एड्र्ड इन कॉन्फिग फाइल
कामागाटोस

1
IIS के साथ IISnode के पीछे प्रॉक्सी के रूप में, app.enable('trust proxy')उपयोग करने के लिए भी काम करता है req.ip। सिवाय मैं इसके साथ बंदरगाह मिलता है 1.2.3.4:56789। उस पट्टी को करने के लिए, मैंvar ip = req.ip.split(':')[0]
क्रिस्टियान वेस्टरबीक

क्या यह समाधान सुरक्षित है?
डैनियल Kmak

3
मुझे लगता है कि इस उत्तर में सुरक्षा का अभाव है और अपडेट करने की आवश्यकता है। आपको हमेशा यह परिभाषित करना चाहिए कि कौन सा आपके आवेदन पर भरोसा करता है। कम से कम स्पोकन उत्तर में स्पूफिंग के बारे में थोड़ा नोटिस है। उस ने कहा, यदि आप एक्सप्रेस का उपयोग कर रहे हैं तो इस तरह से पुस्तकालय का उपयोग करना बेहतर उपाय है, लेकिन उद्धृत कोड गलत है और लिंक किए गए संसाधन पर नहीं मिला है।
फिल

54

में nginx.confफ़ाइल:
proxy_set_header X-Real-IP $remote_addr;

में node.jsसर्वर फ़ाइल:
var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;

ध्यान दें कि एक्सप्रेस हेडर को कम करता है


3
ढेर अतिप्रवाह में आपका स्वागत है! केवल कोड का एक खंड पोस्ट करने के बजाय, कृपया बताएं कि यह कोड समस्या का हल क्यों निकालता है। स्पष्टीकरण के बिना, यह एक उत्तर नहीं है।
आर्टीमिक्स

1
@ququzone का जवाब ठीक है। स्पष्टीकरण "एक्स-रियल-आईपी" नाम के अनुरोध पर एक कस्टम हेडर सेट किया गया है जो आगंतुक से मूल आईपी पता लेता है। यह मेरे लिए नोड और सॉकेट के साथ काम करता है।
कॉफ़ेकेड

8
मेरे लिए, हेडर में कैपिटल अक्षरों के साथ req.headers['x-real-ip']भी आईपी ​​एड्रेस उपलब्ध nginx.confहै।
निक सुमिको

यही मेरे लिए इसका हल है। यहां तक ​​कि विश्वास-प्रॉक्सी के साथ सच करने के लिए, यह अभी भी स्थानीय 127.0.0.1 पते
डेविड

30

विशेष रूप से नोड के लिए, घटना कनेक्शन के तहत http सर्वर घटक के लिए प्रलेखन कहता है:

[ट्रिगर] जब एक नई टीसीपी स्ट्रीम स्थापित होती है। [] सॉकेट एक प्रकार का जाल है। आमतौर पर उपयोगकर्ता इस ईवेंट को एक्सेस नहीं करना चाहेंगे। विशेष रूप से, सॉकेट पठनीय घटनाओं का उत्सर्जन नहीं करेगा क्योंकि प्रोटोकॉल पार्सर सॉकेट से कैसे जुड़ता है। सॉकेट पर भी पहुँचा जा सकता है request.connection

तो, इसका मतलब request.connectionहै कि एक सॉकेट है और प्रलेखन के अनुसार वास्तव में एक सॉकेट है ।remoteAddress विशेषता जो प्रलेखन के अनुसार है:

दूरस्थ आईपी पते का स्ट्रिंग प्रतिनिधित्व। उदाहरण के लिए, '74 .125.127.100 'या' 2001: 4860: a005 :: 68 '।

एक्सप्रेस के तहत, अनुरोध ऑब्जेक्ट भी नोड http अनुरोध ऑब्जेक्ट का एक उदाहरण है, इसलिए यह दृष्टिकोण अभी भी काम करना चाहिए।

हालाँकि, Express.js के तहत अनुरोध में पहले से ही दो विशेषताएँ हैं: req.ip और req.ips

req.ip

दूरस्थ पता लौटें, या जब "प्रॉक्सी पर विश्वास करें" सक्षम हो - अपस्ट्रीम एड्रेस।

req.ips

जब "विश्वास प्रॉक्सी" है true, तो "एक्स-फॉरवर्ड-फॉर" आईपी पते की सूची को पार्स करें और एक सरणी लौटाएं, अन्यथा एक खाली सरणी वापस आ गई है। उदाहरण के लिए यदि मान "क्लाइंट, प्रॉक्सी 1, प्रॉक्सी 2" था, तो आपको सरणी ["क्लाइंट", "प्रॉक्सी 1", "प्रॉक्सी 2"] प्राप्त होगा, जहां "प्रॉक्सी 2" सबसे नीचे की धारा है।

यह ध्यान देने योग्य हो सकता है कि, मेरी समझ के अनुसार, एक्सप्रेस req.ipएक बेहतर दृष्टिकोण है req.connection.remoteAddress, क्योंकि req.ipइसमें वास्तविक ग्राहक आईपी (बशर्ते कि विश्वसनीय प्रॉक्सी व्यक्त में सक्षम हो), जबकि दूसरे में प्रॉक्सी का आईपी पता हो सकता है (यदि वहां है) एक)।

यही कारण है कि वर्तमान में स्वीकृत उत्तर बताता है:

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

req.headers['x-forwarded-for']एक्सप्रेस के बराबर हो जाएगा req.ip


11
  1. जोड़ना app.set('trust proxy', true)
  2. का प्रयोग करें req.ipया req.ipsहमेशा की तरह

2
जाने का यह रास्ता है। देखें expressjs.com/en/guide/behind-proxies.html जानकारी के लिए।
ओ। जोन्स

इतना आसान और संक्षिप्त। एक सरल उत्तर से प्यार करें।
गिल्बर्ट- v

7

यह इस उत्तर के लिए सिर्फ अतिरिक्त जानकारी है ।

यदि आप उपयोग कर रहे हैं nginx, तो आप proxy_set_header X-Real-IP $remote_addr;साइट के लिए स्थान ब्लॉक में जोड़ देंगे । /etc/nginx/sites-available/www.example.comउदाहरण के लिए। यहाँ एक उदाहरण सर्वर ब्लॉक है।

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

    location / {
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_pass http://127.0.1.1:3080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

रीस्टार्ट करने के बाद nginx, आप अपने node/ expressएप्लिकेशन रूट्स में आईपी एक्सेस कर पाएंगेreq.headers['x-real-ip'] || req.connection.remoteAddress;


3

यदि आप ठीक से कॉन्फ़िगर किया है, तो प्रॉक्सी के पीछे एक्सप्रेस के अनुसार , req.ipरिवर्स प्रॉक्सी को ध्यान में रखा गया trust proxyहै। इसलिए यह बेहतर है req.connection.remoteAddressजो नेटवर्क लेयर और प्रॉक्सी से अनभिज्ञ है।


3

मैंने उस उद्देश्य के लिए एक पैकेज लिखा। आप इसे एक्सप्रेस मिडलवेयर के रूप में उपयोग कर सकते हैं। मेरा पैकेज यहां प्रकाशित किया गया है: https://www.npmjs.com/package/express-ip

आप मॉड्यूल का उपयोग करके स्थापित कर सकते हैं

npm i express-ip

प्रयोग

const express = require('express');
const app = express();
const expressip = require('express-ip');
app.use(expressip().getIpInfoMiddleware);

app.get('/', function (req, res) {
    console.log(req.ipInfo);
});

1
आप पोस्ट में संबद्धता का खुलासा करना चाहिए जब आप के साथ संबद्ध कर रहे हैं कुछ को जोड़ने। यदि आप संबद्धता का खुलासा नहीं करते हैं, तो इसे स्पैम माना जाता है। प्रकटीकरण स्पष्ट होना चाहिए, लेकिन औपचारिक होने की आवश्यकता नहीं है (उदाहरण के लिए अपनी निजी सामग्री के लिए: "मेरी साइट पर ...", "मेरे ब्लॉग पर ...", आदि)। देखें: क्या "अच्छा" आत्म प्रचार को दर्शाता है? , आत्म-प्रचार के बारे में कुछ सुझाव और सलाह , स्टैक ओवरफ्लो के लिए "स्पैम" की सटीक परिभाषा क्या है? , और क्या कुछ स्पैम बनाता है
मकेन

2

मुझे पता है कि इस सवाल का जवाब दिया गया है, लेकिन यहाँ मुझे काम करने के लिए कैसे मिला।

let ip = req.connection.remoteAddress.split(`:`).pop();

2

यदि आप तृतीय-पक्ष लाइब्रेरी का उपयोग कर रहे हैं तो ठीक है। आप अनुरोध-आईपी की जांच कर सकते हैं

आप इसका उपयोग कर सकते हैं

import requestIp from 'request-ip';

app.use(requestIp.mw())

app.use((req, res) => {
  const ip = req.clientIp;
});

स्रोत कोड काफी लंबा है, इसलिए मैं यहां कॉपी नहीं करूंगा, आप https://github.com/pbojinov/request-ip/blob/master/src/index.js पर चेक कर सकते हैं

मूल रूप से,

यह अनुरोध में विशिष्ट हेडर की तलाश करता है और मौजूद न होने पर कुछ चूक में गिर जाता है।

उपयोगकर्ता आईपी निम्नलिखित आदेश द्वारा निर्धारित किया जाता है:

  1. X-Client-IP
  2. X-Forwarded-For (हैडर प्रारूप में कई आईपी पते लौटा सकता है: "क्लाइंट आईपी, प्रॉक्सी 1 आईपी, प्रॉक्सी 2 आईपी", इसलिए हम पहले वाले को लेते हैं।)
  3. CF-Connecting-IP (CloudFlare)
  4. Fastly-Client-Ip (तेजी से सीडीएन और फायरबेस होस्टिंग हेडर जब एक क्लाउड फ़ंक्शन के लिए आगे बढ़ते हैं)
  5. True-Client-Ip (अकामाई और क्लाउडफेयर)
  6. X-Real-IP (Nginx प्रॉक्सी / FastCGI)
  7. X-Cluster-Client-IP (रैकस्पेस एलबी, रिवरबेड स्टिंग्रे)
  8. X-Forwarded, Forwarded-Forऔर Forwarded(# 2 के भिन्नरूप)
  9. req.connection.remoteAddress
  10. req.socket.remoteAddress
  11. req.connection.socket.remoteAddress
  12. req.info.remoteAddress

यदि कोई IP पता नहीं मिल सकता है, तो वह वापस आ जाएगा null

खुलासा: मैं लाइब्रेरी से जुड़ा नहीं हूं।


1

इसने मेरे लिए बाकियों से बेहतर काम किया। मेरी साइटें क्लाउडफ़ेयर के पीछे हैं और इसकी आवश्यकता प्रतीत हुई cf-connecting-ip

req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress

प्रॉक्सी के पीछे एक्सप्रेस का परीक्षण नहीं किया क्योंकि उसने इस cf-connecting-ipहेडर के बारे में कुछ नहीं कहा ।


1

भड़कना, nginx और x-real-ip समर्थन के साथ

var user_ip;

    if(req.headers['cf-connecting-ip'] && req.headers['cf-connecting-ip'].split(', ').length) {
      let first = req.headers['cf-connecting-ip'].split(', ');
      user_ip = first[0];
    } else {
      let user_ip = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
    }

1

मेरे मामले में, इस समाधान के समान , मैंने निम्नलिखित एक्स-फॉरवर्ड-फॉर एप्रोच का उपयोग करके समाप्त किया:

let ip = (req.headers['x-forwarded-for'] || '').split(',')[0];

x-forwarded-forहैडर अंतिम गंतव्य सर्वर के लिए सभी तरह मूल से आईपी के मार्ग को जोड़ना जारी रखेगा, इस प्रकार यदि आपको मूल ग्राहक के आईपी को पुनः प्राप्त करने की आवश्यकता है, तो यह सरणी का पहला आइटम होगा ।


0

var ip = req.connection.remoteAddress;

ip = ip.split (':') [3];


ouput इस प्रकार है: - :: ffff: XXX.XX.XX.XX इससे हमें आईपी मिलेगा
भुलावत अजय

3
मुझे लगता है कि ip = ip.split(':').pop();इस मामले में बल्लेबाज़ी होगी अगर सामान्य आईपी यानी 127.0.0.1 आ जाएगा तो भी यह आपको आईपी देने में सक्षम होगा।
9


0

morganक्लाइंट आईपी पते के सभी लॉगिंग wkk @kakopappa समाधान प्लस लॉगिंग:

morgan.token('client_ip', function getId(req) {
    return req.client_ip
});
const LOG_OUT = ':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" :client_ip'
self.app.use(morgan(LOG_OUT, {
    skip: function(req, res) { // custom logging: filter status codes
        return res.statusCode < self._options.logging.statusCode;
    }
}));

// could-flare, nginx and x-real-ip support
var getIpInfoMiddleware = function(req, res, next) {
    var client_ip;
    if (req.headers['cf-connecting-ip'] && req.headers['cf-connecting-ip'].split(', ').length) {
        var first = req.headers['cf-connecting-ip'].split(', ');
        client_ip = first[0];
    } else {
        client_ip = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
    }
    req.client_ip = client_ip;
    next();
};
self.app.use(getIpInfoMiddleware);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.