Come determinare l'indirizzo IP di un utente nel nodo


349

Come posso determinare l'indirizzo IP di una determinata richiesta dall'interno di un controller? Ad esempio (in espresso):

app.post('/get/ip/address', function (req, res) {
    // need access to IP address here
})

22
Se stai usando Express puoi usare req.ip source - expressjs.com/en/api.html#req.ip
FrickeFresh,


16
Per coloro che stanno lavorando localhost- come ho fatto io, il risultato per tutte le risposte di seguito (quasi tutte le risposte funziona) potrebbe venire ::1. Questo mi ha confuso per qualche tempo. Successivamente ho scoperto che si ::1tratta di un vero indirizzo IP e di una IPV6notazione per localhost. Hope this helps someone
Pramesh Bajracharya,

Risposte:


452

Nel tuo requestoggetto c'è una proprietà chiamata connection, che è un net.Socketoggetto. L'oggetto net.Socket ha una proprietà remoteAddress, quindi dovresti essere in grado di ottenere l'IP con questa chiamata:

request.connection.remoteAddress

Vedi documentazione per http e net

MODIFICARE

Come sottolinea @juand nei commenti, il metodo corretto per ottenere l'IP remoto, se il server è dietro un proxy, è request.headers['x-forwarded-for']


6
Questo mi dà un indirizzo IP diverso da quello che whatismyip.com mi dà. Perché dovrebbe essere?
Shamoon,

3
Ho il mio servizio API installato su un'istanza no.de. Quando provo ad accedervi dal mio computer, ottengo un indirizzo IP di "10.2.XXX.YYY" mentre il mio IP nel mondo reale è "67.250.AAA.BBB"
Shamoon,

7
request.headers ['X-Forwarded-For']
0x6A75616E

4
Si noti che net.Stream ora è net.Socket e la documentazione risiede qui: nodejs.org/api/net.html#net_class_net_socket
monsur

4
Per chiunque sia interessato, per Heroku è: 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);

Si noti che a volte è possibile ottenere più di un indirizzo IP req.headers['x-forwarded-for']. Inoltre, x-forwarded-fornon verrà sempre impostata un'intestazione che potrebbe generare un errore.

Il formato generale del campo è:

x-Forwarded-For: client, proxy1, proxy2, proxy3

dove il valore è un elenco separato da virgole + spazio di indirizzi IP, il più a sinistra è il client originale e ogni proxy successivo che ha passato la richiesta aggiungendo l'indirizzo IP da cui ha ricevuto la richiesta. In questo esempio, la richiesta passa attraverso proxy1, proxy2e poi proxy3. proxy3appare come indirizzo remoto della richiesta.

Questa è la soluzione suggerita da Arnav Gupta con una correzione che Martin ha suggerito di seguito nei commenti per i casi in cui x-forwarded-fornon è impostato:

var ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() || 
         req.connection.remoteAddress || 
         req.socket.remoteAddress || 
         req.connection.socket.remoteAddress

9
Come prevenire lo spoofing di queste intestazioni però?
Domi,

8
Questo di solito funziona bene, ma per qualche motivo di recente ho ricevuto l'errore "Impossibile leggere la proprietà 'remoteAddress' di undefined" perché apparentemente tutto era nullo / non definito, incluso req.connection.socket. Non sono sicuro del perché / quali condizioni lo causino, ma sarebbe bene verificare che req.connection.socketesista per evitare il crash del server in questo caso.
Matt Browne,

9
Ultima riga req.connection.socket.remote Errore di lancio dell'indirizzo. Stai attento.
anno

11
L'indirizzo IP restituito è :: 1. Perché?
Bagusflyer,

3
Guardando come funziona pop (), sembra che otterrai l'ultimo proxy e non il client che è quello che vuoi. Ho sbagliato?
Michel,


31

Puoi rimanere ASCIUTTO e usare solo node-ipware che supporta sia IPv4 che IPv6 .

Installare:

npm install ipware

Nel tuo app.js o 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();
});

Farà il tentativo migliore di ottenere l'indirizzo IP dell'utente o restituisce 127.0.0.1per indicare che non è stato possibile determinare l'indirizzo IP dell'utente. Dai un'occhiata al file README per le opzioni avanzate.


40
"o restituisce 127.0.0.1 per indicare che non è stato possibile determinare l'indirizzo IP dell'utente" C'è una differenza abbastanza grande tra 127.0.0.1 e sconosciuto ...
Nepoxx

4
Mi ha restituito qualcosa di strano :ffff:(not my IP address)quando testato da Heroku. La risposta di @ edmar-miyake funziona correttamente per me.
Nilloc,

Mi chiedo quale sarebbe l'IP se tu dovessi usare la ricerca right2left nel caso 'x-forwarded-for'. var ip_info = get_ip (req, right_most_proxy = True), come in alcune impostazioni, l'IP client potrebbe essere l'IP più corretto.
un33k,

2
Quel metodo sta tornando clientIp: '::1'per me. Non sembra funzionare.
JamEngulfer,

@JamEngulfer - ipware funziona solo se l'indirizzo IP viene passato correttamente alla tua app tramite request.headers []. esempio: AWS LBS invia l'indirizzo IP in 'x-forwarded-for' mentre NginX personalizzato utilizza molte altre variabili. ipware fa il tentativo migliore per capire l'indirizzo IP, ma solo se l'IP è stato trasmesso nelle intestazioni.
un33k

19

Puoi usare request-ip per recuperare l'indirizzo IP di un utente. Gestisce alcuni dei diversi casi limite, alcuni dei quali sono menzionati nelle altre risposte.

Divulgazione: ho creato questo modulo

Installare:

npm install request-ip

Nella tua 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();
};

Spero che sia di aiuto


2
controllando il codice sorgente del pacchetto request-ip su github.com/pbojinov/request-ip/blob/master/index.js controlla x-forwarded-for e tutti i tipi di altre intestazioni per popolari bilanciatori del carico come AWS ELB, Cloudflare , Akamai, nginx, Rackspace LB e Stingray di Riverbed
Giorgio,

1
ritorna nullper me.
S.M_Emamian,

La stessa cosa invece usarequest.headers['x-forwarded-for']
Prathamesh More

19

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

Se l' x-forwarded-forintestazione è lì, allora usalo, altrimenti usa la .remoteAddressproprietà.

L' x-forwarded-forintestazione viene aggiunta alle richieste che passano attraverso i bilanciatori del carico (o altri tipi di proxy) impostati per HTTP o HTTPS (è anche possibile aggiungere questa intestazione alle richieste quando si esegue il bilanciamento a livello TCP utilizzando il protocollo proxy ). Questo perché la request.connection.remoteAddressproprietà conterrà l'indirizzo IP privato del bilanciamento del carico anziché l'indirizzo IP pubblico del client. Usando un'istruzione OR , nell'ordine sopra, controlli l'esistenza di x-forwarded-forun'intestazione e la usi se esiste altrimenti usa il request.connection.remoteAddress.


12

La seguente funzione ha tutti i casi coperti aiuterà

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

Nota che gli IP hanno una via di , mezzo per me.
ThomasReggi,

8

Esistono due modi per ottenere l'indirizzo IP:

  1. let ip = req.ip

  2. let ip = req.connection.remoteAddress;

Ma c'è un problema con gli approcci di cui sopra.

Se stai eseguendo la tua app dietro Nginx o qualsiasi proxy, lo saranno tutti i singoli indirizzi IP 127.0.0.1 .

Quindi, la soluzione migliore per ottenere l'indirizzo IP dell'utente è: -

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

6

Se stai utilizzando la versione 3.x o successiva di express, puoi utilizzare l'impostazione del proxy di fiducia ( http://expressjs.com/api.html#trust.proxy.options.table ) e percorrerà la catena di indirizzi in l'intestazione x-forwarded-for e inserisci l'ultimo ip nella catena che non hai configurato come proxy attendibile nella proprietà ip sull'oggetto req.


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


1
Hai ragione, se vuoi l'ip come stringa, puoi sostituire l'ultima riga con: ip = ip.split (':'). Slice (-1) [0]
Ahmad Agbaryah

Le risposte di solo codice sono scoraggiate. Ci può spiegare come questa risposta è migliore rispetto al più vecchio, meglio spiegato, e (molto) più upvoted risposte ?
Dan Dascalescu

5

Avvertimento:

Non utilizzarlo solo alla cieca per importanti limiti di velocità:

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

È molto facile falsificare:

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

In tal caso, l'indirizzo IP reale dell'utente sarà:

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

Sono sorpreso che nessun'altra risposta abbia menzionato questo.


La risposta superiore fa gestire questo pop()ing dalla matrice, che è più generale di ottenere l'elemento di indice 1, che può essere ingannato da curl --header "X-Forwarded-For: 1.2.3.4, 5.6.7.8" "https://example.com".
Dan Dascalescu

3

Se ottieni più IP, questo funziona per me:

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


3

Ottieni l'ip remoto in nodejs:

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

3

Nel nodo 10.14, dietro nginx, è possibile recuperare l'ip richiedendolo tramite l'intestazione nginx in questo modo:

proxy_set_header X-Real-IP $remote_addr;

Quindi nel tuo app.js:

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

Successivamente, ovunque tu voglia che appaia:

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

2

Mi rendo conto che è stata data una risposta a morte, ma ecco una versione ES6 moderna che ho scritto che segue gli standard eslint basati su airbnb.

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

L'intestazione X-Forwarded-For può contenere un elenco separato da virgole di IP proxy. L'ordine è client, proxy1, proxy2, ..., proxyN. Nel mondo reale, le persone implementano proxy che possono fornire tutto ciò che vogliono in questa intestazione. Se sei dietro un bilanciamento del carico o qualcosa del genere, puoi almeno fidarti che il primo IP nell'elenco è almeno qualunque proxy abbia ricevuto una richiesta.


1

Se stai usando Graphql-Yoga puoi usare la seguente funzione:

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
}


-7

Ho avuto lo stesso problema ... sono anche nuovo su JavaScript ma ho risolto questo problema con req.connection.remoteAddress; che mi ha dato l'indirizzo IP (ma in formato ipv6 :: ffff.192.168.0.101) e quindi .slice per rimuovere le prime 7 cifre.

var ip = req.connection.remoteAddress;

if (ip.length < 15) 
{   
   ip = ip;
}
else
{
   var nyIP = ip.slice(7);
   ip = nyIP;
}

questo non è un buon metodo, in quanto ipv6 NON è composto solo da 7 cifre + IPv4, ma può essere totalmente diverso.
Radek,

@Radek se si convalida l'inizio dell'indirizzo, è conforme alle specifiche (consultare en.wikipedia.org/wiki/IPv6_address ricerca ctrl-f per "IPv4-mapped") ip= (ip.length<15?ip:(ip.substr(0,7)==='::ffff:'?ip.substr(7):undefined))sostituirà il codice if ... nel precedente
non sincronizzato

Avvolgo personalmente getClientIp () da npm request-ip per creare 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)); }che accetta come input un IP precedentemente recuperato o un oggetto richiesta come input e, di conseguenza, fornisce ip o indefinito
non sincronizzato
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.