Cómo determinar la dirección IP de un usuario en el nodo

349

¿Cómo puedo determinar la dirección IP de una solicitud dada desde un controlador? Por ejemplo (en expreso):

app.post('/get/ip/address', function (req, res) {
    // need access to IP address here
})
Shamoon
fuente
22
Si está utilizando Express, puede usar req.ip source - expressjs.com/en/api.html#req.ip
FrickeFresh
Pruebe esto: github.com/indutny/node-ip
Stephen Último
16
Para aquellos que están trabajando localhost, como lo hice yo, el resultado de todas las respuestas a continuación (casi todas las respuestas funciona) podría llegar ::1. Esto me confundió por algún tiempo. Más tarde descubrí que ::1es una dirección IP real y una IPV6notación para localhost. Hope this helps someone
Pramesh Bajracharya

Respuestas:

452

En su requestobjeto hay una propiedad llamada connection, que es un net.Socketobjeto. El objeto net.Socket tiene una propiedad remoteAddress, por lo tanto, debería poder obtener la IP con esta llamada:

request.connection.remoteAddress

Ver documentación para http y net

EDITAR

Como @juand señala en los comentarios, el método correcto para obtener la IP remota, si el servidor está detrás de un proxy, es request.headers['x-forwarded-for']

topek
fuente
66
Esto me da una dirección IP diferente de la que me da whatismyip.com. ¿Por qué sería eso?
Shamoon
3
Tengo mi servicio API instalado en una instancia no.de. Cuando intento acceder desde mi computadora, obtengo una dirección IP de "10.2.XXX.YYY", mientras que mi IP del mundo real es "67.250.AAA.BBB"
Shamoon
77
es request.headers ['X-Fordered-For']
0x6A75616E
44
Tenga en cuenta que net.Stream ahora es net.Socket, y la documentación se encuentra aquí: nodejs.org/api/net.html#net_class_net_socket
monsur
44
Para cualquiera que esté interesado, para Heroku es: request.headers['x-forwarded-for']
FueledPubuling
407
var ip = req.headers['x-forwarded-for'] || 
     req.connection.remoteAddress || 
     req.socket.remoteAddress ||
     (req.connection.socket ? req.connection.socket.remoteAddress : null);

Tenga en cuenta que a veces puede obtener más de una dirección IP req.headers['x-forwarded-for']. Además, x-forwarded-forno siempre se establecerá un encabezado que pueda generar un error.

El formato general del campo es:

x-reenviado-para: client, proxy1, proxy2, proxy3

donde el valor es una lista de direcciones IP separadas por comas y espacios, siendo la izquierda el cliente original y cada proxy sucesivo que pasó la solicitud agregando la dirección IP de donde recibió la solicitud. En este ejemplo, la solicitud pasa a través de proxy1, proxy2y, a continuación proxy3. proxy3aparece como dirección remota de la solicitud.

Esta es la solución sugerida por Arnav Gupta con una solución que Martin ha sugerido a continuación en los comentarios para casos en los x-forwarded-forque no está configurado:

var ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() || 
         req.connection.remoteAddress || 
         req.socket.remoteAddress || 
         req.connection.socket.remoteAddress
Edmar Miyake
fuente
99
Sin embargo, ¿cómo evitar la falsificación de estos encabezados?
Domi
8
Esto generalmente funciona bien, pero por alguna razón recientemente recibí el error "No se puede leer la propiedad 'remoteAddress' de undefined" porque aparentemente todo era nulo / indefinido, incluido req.connection.socket. No estoy seguro de por qué / qué condiciones hacen que ese sea el caso, pero sería bueno verificar que req.connection.socketexista para evitar que su servidor se bloquee si esto sucede.
Matt Browne
99
Última línea req.connection.socket.remoteAddress throwing error. Se cuidadoso.
yAnTar
11
La dirección IP devuelta es :: 1. ¿Por qué?
Bagusflyer
3
Mirando la forma en que funciona pop (), parece que va a obtener el último proxy y no el cliente que es lo que desea. ¿Me equivoco?
Michel
84

Si usa express ...

req.ip

Estaba buscando esto y luego pensé, espero, estoy usando express. Duh

Jason Sebring
fuente
Devolverá una variación de 127.0.0.1 si el servidor se ejecuta detrás de un proxy. Use la respuesta de Edmar o establezca x-real-ip .
Dan Dascalescu
31

Puede permanecer SECO y simplemente usar node-ipware que sea compatible con IPv4 e IPv6 .

Instalar en pc:

npm install ipware

En su 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();
});

Hará el mejor intento de obtener la dirección IP del usuario o regresará 127.0.0.1para indicar que no pudo determinar la dirección IP del usuario. Eche un vistazo al archivo README para ver las opciones avanzadas.

un33k
fuente
40
"o devuelve 127.0.0.1 para indicar que no pudo determinar la dirección IP del usuario" Hay una gran diferencia entre 127.0.0.1 y desconocido ...
Nepoxx
44
Me devolvió algo extraño :ffff:(not my IP address)cuando lo probé desde Heroku. La respuesta de @ edmar-miyake está funcionando correctamente para mí.
Nilloc
Me pregunto cuál sería la IP si usara la búsqueda right2left en el caso 'x-forward-for'. var ip_info = get_ip (req, right_most_proxy = True), como en algunas configuraciones, la IP del cliente podría ser la IP más correcta.
un33k
2
Ese método está volviendo clientIp: '::1'para mí. No parece funcionar.
JamEngulfer
@JamEngulfer: ipware solo funciona si la dirección IP se transfiere correctamente a su aplicación a través de request.headers []. ejemplo: AWS LBS envía la dirección IP en 'x-forwards-for' mientras que NginX personalizado puede usar otras variables. ipware hace el mejor intento de averiguar la dirección IP, pero solo si la IP se ha transmitido en los encabezados.
un33k
19

Puede usar request-ip , para recuperar la dirección IP de un usuario. Maneja algunos de los diferentes casos límite, algunos de los cuales se mencionan en las otras respuestas.

Divulgación: creé este módulo

Instalar en pc:

npm install request-ip

En su aplicación:

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

Espero que esto ayude

pbojinov
fuente
2
comprobando el código fuente del paquete request-ip en github.com/pbojinov/request-ip/blob/master/index.js comprueba x-reenviado-y todo tipo de otros encabezados para equilibradores de carga populares como AWS ELB, Cloudflare , Akamai, nginx, Rackspace LB y Riverbed's Stingray
Giorgio
1
Vuelve nullpor mí.
S.M_Emamian
Lo mismo en lugar de usarrequest.headers['x-forwarded-for']
Prathamesh Más
19

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

Si el x-forwarded-forencabezado está allí, úselo; de lo contrario, use la .remoteAddresspropiedad

El x-forwarded-forencabezado se agrega a las solicitudes que pasan a través de equilibradores de carga (u otros tipos de proxy) configurados para HTTP o HTTPS (también es posible agregar este encabezado a las solicitudes cuando se equilibra a nivel TCP utilizando el protocolo proxy ). Esto se debe a que la request.connection.remoteAddresspropiedad contendrá la dirección IP privada del equilibrador de carga en lugar de la dirección IP pública del cliente. Al usar una instrucción OR , en el orden anterior, verifica la existencia de un x-forwarded-forencabezado y lo usa si existe, de lo contrario, use el request.connection.remoteAddress.

Ben Davies
fuente
12

La siguiente función tiene todos los casos cubiertos ayudará

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
fuente
Tenga en cuenta que los ips tienen un , intermedio para mí.
ThomasReggi
8

Hay dos formas de obtener la dirección IP:

  1. let ip = req.ip

  2. let ip = req.connection.remoteAddress;

Pero hay un problema con los enfoques anteriores.

Si está ejecutando su aplicación detrás de Nginx o cualquier proxy, todas las direcciones IP lo serán 127.0.0.1.

Entonces, la mejor solución para obtener la dirección IP del usuario es: -

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

Si está utilizando la versión express 3.xo superior, puede usar la configuración del proxy de confianza ( http://expressjs.com/api.html#trust.proxy.options.table ) y recorrerá la cadena de direcciones en el encabezado x-forwards-for y coloque la última ip en la cadena que no haya configurado como proxy de confianza en la propiedad ip en el objeto req.

Michael Lang
fuente
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
fuente
1
Tiene razón, si desea la ip como cadena, puede reemplazar la última línea con: ip = ip.split (':'). Slice (-1) [0]
Ahmad Agbaryah
Se desaconsejan las respuestas de solo código. ¿Puede explicar cómo esta respuesta es mejor que el más viejo, mejor explicado, y (mucho) más upvoted respuestas ?
Dan Dascalescu
5

Advertencia:

No utilice esto ciegamente para limitar la velocidad importante:

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

Es muy fácil falsificar:

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

En ese caso, la dirección IP real del usuario será:

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

Me sorprende que ninguna otra respuesta haya mencionado esto.


fuente
La respuesta más común hace manejar esto pop()ing de la matriz, lo que es más general que conseguir el elemento en el índice 1, que puede ser engañado por curl --header "X-Forwarded-For: 1.2.3.4, 5.6.7.8" "https://example.com".
Dan Dascalescu
3

Si obtienes múltiples IP, esto funciona para mí:

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

Kirill Chatrov
fuente
3

Simple obtener ip remota en nodejs:

var ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
Vlogs de TI
fuente
3

En el nodo 10.14, detrás de nginx, puede recuperar la ip solicitándola a través del encabezado nginx de esta manera:

proxy_set_header X-Real-IP $remote_addr;

Luego en tu app.js:

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

Después de eso, donde quiera que aparezca:

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

Me doy cuenta de que esto ha sido respondido a muerte, pero aquí hay una versión moderna de ES6 que escribí que sigue los estándares de base de 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;
};

El encabezado X-Fordered-For puede contener una lista de IP proxy separadas por comas. El pedido es cliente, proxy1, proxy2, ..., proxyN. En el mundo real, las personas implementan proxies que pueden suministrar lo que quieran en este encabezado. Si está detrás de un equilibrador de carga o algo así, al menos puede confiar en que la primera IP de la lista es, al menos, cualquier proxy que haya recibido alguna solicitud.

Misha Nasledov
fuente
1

Si está utilizando Graphql-Yoga, puede utilizar la siguiente función:

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
fuente
0

Estoy usando express detrás de nginx y

req.headers.origin

hizo el truco para mí

Matan Livne
fuente
-7

Tuve el mismo problema ... también soy nuevo en javascript pero lo resolví con req.connection.remoteAddress; eso me dio la dirección IP (pero en formato ipv6 :: ffff.192.168.0.101) y luego .slice para eliminar los 7 primeros dígitos.

var ip = req.connection.remoteAddress;

if (ip.length < 15) 
{   
   ip = ip;
}
else
{
   var nyIP = ip.slice(7);
   ip = nyIP;
}
aCo
fuente
este no es un buen método, ya que ipv6 NO es solo de 7 dígitos + IPv4, sino que puede ser totalmente diferente.
Radek
@Radek si valida el inicio de la dirección, se ajusta a las especificaciones (ver en.wikipedia.org/wiki/IPv6_address ctrl-f buscar "IPv4-mapped") ip= (ip.length<15?ip:(ip.substr(0,7)==='::ffff:'?ip.substr(7):undefined))reemplazaría el if ... en el código anterior
no sincronizado
Personalmente envuelvo getClientIp () de npm request-ip para crear 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)); }que acepte una ip obtenida previamente o un objeto de solicitud como entrada y, como resultado
no sincronizado