So ermitteln Sie die IP-Adresse eines Benutzers im Knoten

349

Wie kann ich die IP-Adresse einer bestimmten Anfrage innerhalb eines Controllers ermitteln? Zum Beispiel (ausdrücklich):

app.post('/get/ip/address', function (req, res) {
    // need access to IP address here
})
Shamoon
quelle
22
Wenn Sie Express verwenden, können Sie req.ip source - expressjs.com/en/api.html#req.ip
FrickeFresh
Versuchen Sie dies: github.com/indutny/node-ip
Stephen Letzter
16
Für diejenigen, die von localhost- wie ich - arbeiten, könnte das Ergebnis für alle Antworten unten (fast alle Antworten funktionieren) kommen ::1. Das hat mich für einige Zeit verwirrt. Später fand heraus, dass dies ::1eine echte IP-Adresse und eine IPV6Notation für localhost ist. Hope this helps someone
Pramesh Bajracharya

Antworten:

452

In Ihrem requestObjekt gibt es eine Eigenschaft namens connection, die ein net.SocketObjekt ist. Das net.Socket-Objekt hat eine Eigenschaft remoteAddress, daher sollten Sie in der Lage sein, die IP mit diesem Aufruf abzurufen :

request.connection.remoteAddress

Siehe Dokumentation für http und net

BEARBEITEN

Wie @juand in den Kommentaren ausführt, ist die richtige Methode zum Abrufen der Remote-IP, wenn sich der Server hinter einem Proxy befindet request.headers['x-forwarded-for']

topek
quelle
6
Dies gibt mir eine andere IP-Adresse als whatismyip.com. Warum sollte das so sein?
Shamoon
3
Ich habe meinen API-Dienst auf einer no.de- Instanz installiert . Wenn ich versuche, von meinem Computer aus darauf zuzugreifen, erhalte ich die IP-Adresse "10.2.XXX.YYY", während meine reale IP "67.250.AAA.BBB" lautet
Shamoon
7
Es ist request.headers ['X-Forwarded-For']
0x6A75616E
4
Beachten Sie, dass net.Stream jetzt net.Socket ist und die Dokumentation hier gespeichert
Monsur
4
Für alle, deren Interesse, für Heroku ist es: request.headers['x-forwarded-for']
FueledPublishing
407
var ip = req.headers['x-forwarded-for'] || 
     req.connection.remoteAddress || 
     req.socket.remoteAddress ||
     (req.connection.socket ? req.connection.socket.remoteAddress : null);

Beachten Sie, dass Sie manchmal mehr als eine IP-Adresse erhalten können req.headers['x-forwarded-for']. Außerdem x-forwarded-forwird nicht immer ein Header gesetzt, der einen Fehler auslösen kann.

Das allgemeine Format des Feldes lautet:

x-weitergeleitet-für: client, proxy1, proxy2, proxy3

Dabei ist der Wert eine durch Kommas und Leerzeichen getrennte Liste von IP-Adressen, wobei der ursprüngliche Client ganz links steht und jeder nachfolgende Proxy, der die Anforderung übergeben hat, die IP-Adresse hinzufügt, von der er die Anforderung erhalten hat. In diesem Beispiel hat der Antrag durch proxy1, proxy2und dann proxy3. proxy3wird als Remote-Adresse der Anforderung angezeigt.

Dies ist die von Arnav Gupta vorgeschlagene Lösung mit einem Fix, den Martin unten in den Kommentaren für Fälle vorgeschlagen hat, in denen dies x-forwarded-fornicht festgelegt ist:

var ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() || 
         req.connection.remoteAddress || 
         req.socket.remoteAddress || 
         req.connection.socket.remoteAddress
Edmar Miyake
quelle
9
Wie kann man jedoch das Spoofing dieser Header verhindern?
Domi
8
Dies funktioniert normalerweise gut, aber aus irgendeinem Grund habe ich kürzlich den Fehler "Die Eigenschaft 'remoteAddress' von undefined kann nicht gelesen werden" erhalten, da anscheinend alles null / undefined war, einschließlich req.connection.socket. Ich bin nicht sicher, warum / unter welchen Bedingungen dies der Fall ist, aber es wäre gut zu überprüfen, req.connection.socketob dies der Fall ist, um zu verhindern, dass Ihr Server in diesem Fall abstürzt.
Matt Browne
9
Letzte Zeile req.connection.socket.remoteAddress Fehler auslösen. Sei vorsichtig.
yAnTar
11
Die zurückgegebene IP-Adresse lautet :: 1. Warum?
Bagusflyer
3
Wenn Sie sich die Funktionsweise von pop () ansehen, scheinen Sie den letzten Proxy zu erhalten und nicht den Client, den Sie möchten. Liege ich falsch?
Michel
84

Bei Verwendung von Express ...

req.ip

Ich habe das nachgeschlagen, dann war ich wie warten, ich benutze Express. Duh.

Jason Sebring
quelle
Gibt eine Variation von 127.0.0.1 zurück, wenn der Server hinter einem Proxy ausgeführt wird. Verwenden Sie Edmars Antwort oder stellen Sie x-real-ip ein .
Dan Dascalescu
31

Sie können bleiben DRY und nur verwenden Knoten-ipware dass unterstützt sowohl IPv4 und IPv6 .

Installieren:

npm install ipware

In Ihrer app.js oder Middleware:

var getIP = require('ipware')().get_ip;
app.use(function(req, res, next) {
    var ipInfo = getIP(req);
    console.log(ipInfo);
    // { clientIp: '127.0.0.1', clientIpRoutable: false }
    next();
});

Es wird der beste Versuch unternommen, die IP-Adresse des Benutzers abzurufen, oder es wird zurückgegeben, 127.0.0.1um anzuzeigen, dass die IP-Adresse des Benutzers nicht ermittelt werden konnte. In der README- Datei finden Sie erweiterte Optionen.

un33k
quelle
40
"oder gibt 127.0.0.1 zurück, um anzuzeigen, dass die IP-Adresse des Benutzers nicht ermittelt werden konnte" Es gibt einen ziemlich großen Unterschied zwischen 127.0.0.1 und unbekannt ...
Nepoxx
4
Es gab etwas Seltsames für mich zurück, :ffff:(not my IP address)als es von Heroku getestet wurde. @ edmar-miyakes Antwort funktioniert für mich richtig.
Nilloc
Ich frage mich, was die IP wäre, wenn Sie die Suche nach right2left im Fall 'x-forwarded-for' verwenden würden. var ip_info = get_ip (req, right_most_proxy = True), da in einigen Setups die Client-IP möglicherweise die am weitesten rechts stehende IP ist.
Un33k
2
Diese Methode kehrt clientIp: '::1'für mich zurück. Es scheint nicht zu funktionieren.
JamEngulfer
@JamEngulfer - IPware funktioniert nur, wenn die IP-Adresse ordnungsgemäß über request.headers [] an Ihre App weitergegeben wird. Beispiel: AWS LBS sendet die IP-Adresse in 'x-forwarded-for', während benutzerdefiniertes NginX viele andere Variablen verwenden. ipware macht den besten Versuch, die IP-Adresse herauszufinden, aber nur, wenn die IP in den Headern weitergegeben wurde.
Un33k
19

Sie können request-ip verwenden , um die IP-Adresse eines Benutzers abzurufen. Es werden einige der verschiedenen Randfälle behandelt, von denen einige in den anderen Antworten erwähnt werden.

Offenlegung: Ich habe dieses Modul erstellt

Installieren:

npm install request-ip

In Ihrer App:

var requestIp = require('request-ip');

// inside middleware handler
var ipMiddleware = function(req, res, next) {
    var clientIp = requestIp.getClientIp(req); // on localhost > 127.0.0.1
    next();
};

Hoffe das hilft

pbojinov
quelle
2
Beim Überprüfen des Quellcodes des Pakets request-ip unter github.com/pbojinov/request-ip/blob/master/index.js wird x-forwarded-for und alle möglichen anderen Header auf beliebte Load Balancer wie AWS ELB, Cloudflare überprüft , Akamai, Nginx, Rackspace LB und Riverbed's Stingray
Giorgio
1
es kehrt nullfür mich zurück.
S.M_Emamian
Das gleiche verwenden Sie stattdessenrequest.headers['x-forwarded-for']
Prathamesh More
19

request.headers['x-forwarded-for'] || request.connection.remoteAddress

Wenn der x-forwarded-forHeader vorhanden ist, verwenden Sie diesen, andernfalls verwenden Sie die .remoteAddressEigenschaft.

Der x-forwarded-forHeader wird zu Anforderungen hinzugefügt, die Load Balancer (oder andere für HTTP oder HTTPS eingerichtete Proxy-Typen) durchlaufen ( dieser Header kann auch zu Anforderungen hinzugefügt werden, wenn der Ausgleich auf TCP- Ebene mithilfe des Proxy-Protokolls erfolgt ). Dies liegt daran, dass die request.connection.remoteAddressEigenschaft die private IP-Adresse des Load Balancers und nicht die öffentliche IP-Adresse des Clients enthält. Mithilfe einer ODER- Anweisung in der obigen Reihenfolge überprüfen x-forwarded-forSie, ob ein Header vorhanden ist, und verwenden ihn, falls vorhanden. Verwenden Sie andernfalls den request.connection.remoteAddress.

Ben Davies
quelle
12

Die folgende Funktion hat alle abgedeckten Fälle helfen

var ip;
if (req.headers['x-forwarded-for']) {
    ip = req.headers['x-forwarded-for'].split(",")[0];
} else if (req.connection && req.connection.remoteAddress) {
    ip = req.connection.remoteAddress;
} else {
    ip = req.ip;
}console.log("client IP is *********************" + ip);
ashishyadaveee11
quelle
Beachten Sie, dass die IPs , für mich einen Zwischenraum haben.
Thomas Reggi
8

Es gibt zwei Möglichkeiten, um die IP-Adresse zu erhalten:

  1. let ip = req.ip

  2. let ip = req.connection.remoteAddress;

Es gibt jedoch ein Problem mit den oben genannten Ansätzen.

Wenn Sie Ihre App hinter Nginx oder einem Proxy ausführen, wird jede einzelne IP-Adresse verwendet 127.0.0.1.

Die beste Lösung, um die IP-Adresse des Benutzers zu erhalten, ist:

let ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
Mansi Teharia
quelle
6

Wenn Sie Express Version 3.x oder höher verwenden, können Sie die Vertrauens-Proxy-Einstellung ( http://expressjs.com/api.html#trust.proxy.options.table ) verwenden, um die Adresskette zu durchlaufen den x-forwarded-for-Header und fügen Sie die neueste IP in der Kette, die Sie nicht als vertrauenswürdiger Proxy konfiguriert haben, in die IP-Eigenschaft des req-Objekts ein.

Michael Lang
quelle
6

function getCallerIP(request) {
    var ip = request.headers['x-forwarded-for'] ||
        request.connection.remoteAddress ||
        request.socket.remoteAddress ||
        request.connection.socket.remoteAddress;
    ip = ip.split(',')[0];
    ip = ip.split(':').slice(-1); //in case the ip returned in a format: "::ffff:146.xxx.xxx.xxx"
    return ip;
}

Ahmad Agbaryah
quelle
1
Sie haben Recht, wenn Sie die IP als Zeichenfolge möchten, können Sie die letzte Zeile durch Folgendes ersetzen: ip = ip.split (':'). Slice (-1) [0]
Ahmad Agbaryah
Von Nur-Code-Antworten wird abgeraten. Können Sie erklären, wie diese Antwort besser ist als die älteren, besser erklärten und (viel) besser bewerteten Antworten ?
Dan Dascalescu
5

Warnung:

Verwenden Sie dies nicht blind für wichtige Ratenbegrenzungen:

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

Es ist sehr leicht zu fälschen:

curl --header "X-Forwarded-For: 1.2.3.4" "https://example.com"

In diesem Fall lautet die tatsächliche IP-Adresse des Benutzers:

let ip = request.headers['x-forwarded-for'].split(',')[1];

Ich bin überrascht, dass keine anderen Antworten dies erwähnt haben.


quelle
Die Top-Antwort tut dies umgehen , indem pop()aus dem Array ing, die allgemeiner ist als das Element am Index 1 bekommen, was werden kann täuschen durch curl --header "X-Forwarded-For: 1.2.3.4, 5.6.7.8" "https://example.com".
Dan Dascalescu
3

Wenn Sie mehrere IPs erhalten, funktioniert dies für mich:

var ipaddress = (req.headers['x-forwarded-for'] || 
req.connection.remoteAddress || 
req.socket.remoteAddress || 
req.connection.socket.remoteAddress).split(",")[0];

Kirill Chatrov
quelle
3

Einfach Remote-IP in NodeJS erhalten:

var ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
IT-Vlogs
quelle
3

In Knoten 10.14 hinter nginx können Sie die IP-Adresse abrufen, indem Sie sie über den nginx-Header wie folgt anfordern:

proxy_set_header X-Real-IP $remote_addr;

Dann in Ihrer app.js:

app.set('trust proxy', true);

Danach, wo immer es erscheinen soll:

var userIp = req.header('X-Real-IP') || req.connection.remoteAddress;
Alexandru
quelle
2

Mir ist klar, dass dies zu Tode beantwortet wurde, aber hier ist eine moderne ES6-Version, die ich geschrieben habe und die den Airbnb-basierten Eslint-Standards entspricht.

const getIpAddressFromRequest = (request) => {
  let ipAddr = request.connection.remoteAddress;

  if (request.headers && request.headers['x-forwarded-for']) {
    [ipAddr] = request.headers['x-forwarded-for'].split(',');
  }

  return ipAddr;
};

Der X-Forwarded-For-Header kann eine durch Kommas getrennte Liste von Proxy-IPs enthalten. Die Reihenfolge ist client, proxy1, proxy2, ..., proxyN. In der realen Welt implementieren Benutzer Proxys, die in diesem Header alles liefern können, was sie wollen. Wenn Sie sich hinter einem Load Balancer oder etwas anderem befinden, können Sie zumindest darauf vertrauen, dass die erste IP in der Liste mindestens der Proxy ist, über den eine Anforderung eingegangen ist.

Mischa Nasledov
quelle
1

Wenn Sie Graphql-Yoga verwenden, können Sie die folgende Funktion verwenden:

const getRequestIpAddress = (request) => {
    const requestIpAddress = request.request.headers['X-Forwarded-For'] || request.request.connection.remoteAddress
    if (!requestIpAddress) return null

    const ipv4 = new RegExp("(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")

    const [ipAddress] = requestIpAddress.match(ipv4)

    return ipAddress
}

Arsham Gh
quelle
-7

Hatte das gleiche Problem ... ich bin auch neu bei Javascript, aber ich habe dies mit req.connection.remoteAddress gelöst; das gab mir die IP-Adresse (aber im IPv6-Format :: ffff.192.168.0.101) und dann .slice , um die 7 ersten Ziffern zu entfernen.

var ip = req.connection.remoteAddress;

if (ip.length < 15) 
{   
   ip = ip;
}
else
{
   var nyIP = ip.slice(7);
   ip = nyIP;
}
aCo
quelle
Dies ist keine gute Methode, da IPv6 NICHT nur 7-stellig + IPv4 ist, sondern völlig anders sein kann.
Radek
@Radek Wenn Sie den Anfang der Adresse überprüfen, entspricht sie der Spezifikation (siehe en.wikipedia.org/wiki/IPv6_address ctrl-f Suche nach "IPv4-mapped") und ip= (ip.length<15?ip:(ip.substr(0,7)==='::ffff:'?ip.substr(7):undefined))ersetzt das if ... im obigen Code
unsynchronized
Ich persönlich verpacke getClientIp () von npm request-ip, um function getClientIp4(req){ var ip=typeof req==='string'?req:getClientIp(req); return (ip.length<15?ip:(ip.substr(0,7)==='::ffff:'?ip.substr(7):undefined)); }eine zu erstellen, die entweder eine zuvor abgerufene IP oder ein Anforderungsobjekt als Eingabe akzeptiert und als Ergebnis eine IP-Adresse oder eine undefinierte IP- Adresse angibt
unsynchronisiert