Express.js: cómo obtener la dirección remota del cliente

No entiendo completamente cómo debería obtener una dirección IP de usuario remoto.

Digamos que tengo una ruta de solicitud simple como:

app.get(/, function (req, res){ var forwardedIpsStr = req.header('x-forwarded-for'); var IP = ''; if (forwardedIpsStr) { IP = forwardedIps = forwardedIpsStr.split(',')[0]; } }); 

¿Es correcto el enfoque anterior para obtener la dirección IP del usuario real o hay una forma mejor? ¿Y los proxies?

Si se está ejecutando detrás de un proxy como NGiNX o lo que tiene, solo entonces debe verificar para ‘x-forward-for’:

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

Si el proxy no es ‘suyo’, no confiaría en el encabezado ‘x-forward-for’ porque puede ser falso.

Si bien la respuesta de @alessioalex funciona, hay otra forma como se indica en la sección Expresiones detrás de los proxies de Express – guide .

  1. Agregue app.enable('trust proxy') a su código de inicialización express.
  2. Cuando desee obtener la ip del cliente remoto, use req.ip o req.ips de la forma habitual (como si no hubiera un proxy inverso)

Hay más opciones disponibles para ‘proxy de confianza’ si necesita algo más sofisticado que confiar en todo lo que se transfiere en el encabezado x-forward-for, y su proxy no elimina el encabezado x-forward-for preexistente de fonts que no son de confianza. Consulte la guía vinculada para más detalles.

NOTA: req.connection.remoteAddress no funcionará con mi solución.

En el archivo nginx.conf :
proxy_set_header X-Real-IP $remote_addr;

En el archivo de servidor node.js :
var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;

Tenga en cuenta que express encabezados en minúsculas

Particularmente para el nodo, la documentación para el componente del servidor http, bajo la conexión del evento dice:

[Disparo] cuando se establece una nueva transmisión TCP. [El] socket es un objeto de tipo net.Socket. Por lo general, los usuarios no querrán acceder a este evento. En particular, el socket no emitirá eventos legibles debido a la forma en que el analizador del protocolo se conecta al socket. El socket también se puede acceder a request.connection .

Entonces, eso significa que request.connection es un socket y de acuerdo con la documentación existe un atributo socket.remoteAddress que de acuerdo a la documentación es:

La representación de cadena de la dirección IP remota. Por ejemplo, ’74 .125.127.100 ‘o’ 2001: 4860: a005 :: 68 ‘.

Debajo de express, el objeto de solicitud también es una instancia del objeto de solicitud HTTP de nodo, por lo que este enfoque debería funcionar.

Sin embargo, en Express.js, la solicitud ya tiene dos atributos: req.ip y req.ips

req.ip

Devuelve la dirección remota o cuando está habilitado el “proxy de confianza”: la dirección ascendente.

req.ips

Cuando “trust proxy” es true , analiza la lista de direcciones IP “X-Forwarded-For” y devuelve una matriz, de lo contrario se devuelve una matriz vacía. Por ejemplo, si el valor fuera “cliente, proxy1, proxy2”, recibiría la matriz [“cliente”, “proxy1”, “proxy2”] donde “proxy2” es el flujo descendente más lejano.

Merece la pena mencionar que, de acuerdo con mi comprensión, el Express req.ip es un mejor enfoque que req.connection.remoteAddress , ya que req.ip contiene la ip del cliente real (siempre que el proxy de confianza esté habilitado en express), mientras que el otro puede contener la dirección IP del proxy (si hay una).

Esa es la razón por la cual la respuesta actualmente aceptada sugiere:

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

El req.headers['x-forwarded-for'] será el equivalente de express req.ip

De acuerdo con Express detrás de los proxies , req.ip ha tenido en cuenta el proxy inverso si ha configurado correctamente el trust proxy . Por lo tanto, es mejor que req.connection.remoteAddress que se obtiene de la capa de red y desconoce el proxy.

  1. Agregar app.set('trust proxy', true)
  2. Use req.ip o req.ips de la manera habitual

Esto funcionó para mí mejor que el rest. Mis sitios están detrás de CloudFlare y parecía requerir cf-connecting-ip .

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

No probé Express detrás de los proxys ya que no decía nada sobre este encabezado cf-connecting-ip .

var ip = req.connection.remoteAddress;

ip = ip.split (‘:’) [3];

El objeto de encabezados tiene todo lo que necesitas, solo haz esto:

var ip = req.headers [‘x-forward-for’]. split (‘,’) [0];