node.js - node - Express.js: cómo obtener la dirección remota del cliente
node js url (9)
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?
- Agregar
app.set(''trust proxy'', true)
- Use
req.ip
oreq.ips
de la manera habitual
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.
El objeto de encabezados tiene todo lo que necesitas, solo haz esto:
var ip = req.headers [''x-forward-for'']. split ('','') [0];
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 expresar encabezados en minúsculas
Esto funcionó para mí mejor que el resto. 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
.
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 expresar, 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.ip
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
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 .
- Agregue
app.enable(''trust proxy'')
a su código de inicialización express. - Cuando desee obtener la ip del cliente remoto, use
req.ip
oreq.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 fuentes que no son de confianza. Consulte la guía vinculada para más detalles.
NOTA: req.connection.remoteAddress
no funcionará con mi solución.
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.
var ip = req.connection.remoteAddress;
ip = ip.split ('':'') [3];