web-dev-qa-db-fra.com

Express.js: comment obtenir l'adresse du client distant

Je ne comprends pas très bien comment obtenir une adresse IP d'utilisateur distant.

Disons que j'ai un itinéraire de demande simple tel que:

app.get(/, function (req, res){
   var forwardedIpsStr = req.header('x-forwarded-for');
   var IP = '';

   if (forwardedIpsStr) {
      IP = forwardedIps = forwardedIpsStr.split(',')[0];  
   }
});

L'approche ci-dessus est-elle correcte pour obtenir la véritable adresse IP de l'utilisateur ou existe-t-il un meilleur moyen? Et qu'en est-il des procurations?

183
Erik

Si vous utilisez un proxy tel que NGiNX ou ce que vous avez, alors vous devriez seulement vérifier s'il y a un 'x-forwarded-for':

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

Si le proxy n'est pas "le vôtre", je ne ferais pas confiance à l'en-tête "x-forwarded-for", car il peut être falsifié.

357
alessioalex

Bien que la réponse de @alessioalex fonctionne, il existe un autre moyen, comme indiqué dans la section Express derrière les proxies de Express - guide .

  1. Ajoutez app.enable('trust proxy') à votre code d’initialisation express.
  2. Lorsque vous voulez obtenir l'ip du client distant, utilisez req.ip ou req.ips de la manière habituelle (comme s'il n'y avait pas de proxy inverse)

Si vous avez besoin de quelque chose de plus sophistiqué, vous disposez de plus d'options pour approuver tout ce qui est passé dans l'en-tête x-forwarded-for. Si votre proxy ne supprime pas l'en-tête préexistant x-forwarded-for des sources non fiables. Voir le guide lié pour plus de détails.

REMARQUE: req.connection.remoteAddress ne fonctionnera pas avec ma solution.

184
Haozhun

Dans le fichier nginx.conf
proxy_set_header X-Real-IP $remote_addr;

Dans le fichier serveur node.js
var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;

Notez que les en-têtes minuscules express

48
ququzone

En particulier pour node, la documentation du composant serveur http, sous connexion à un événement dit:

[Déclenché] lorsqu'un nouveau flux TCP est établi. [Le] socket est un objet de type net.Socket. Habituellement, les utilisateurs ne voudront pas accéder à cet événement. Dans En particulier, le socket n’émettra pas d’événements lisibles à cause de la façon dont l'analyseur de protocole se connecte au socket. La prise peut aussi être consulté à request.connection.

Donc, cela signifie que request.connection est un socket et selon la documentation, il existe bien un socket.remoteAddress attribut qui, selon la documentation, est:

La représentation sous forme de chaîne de l'adresse IP distante. Par exemple, «74,125,127,100» ou «2001: 4860: a005 :: 68».

Sous express, l'objet de requête est également une instance de l'objet de requête http Node. Cette approche devrait donc toujours fonctionner. 

Cependant, sous Express.js, la demande a déjà deux attributs: req.ip et req.ips

req.ip 

Renvoie l'adresse distante ou, lorsque "proxy de confiance" est activé, l'adresse en amont.

req.ips 

Lorsque "trust proxy" est true, analysez la liste d'adresses IP "X-Forwarded-For" et renvoyez un tableau, sinon un tableau vide correspond à revenu. Par exemple, si la valeur était "client, proxy1, proxy2" vous recevrait le tableau ["client", "proxy1", "proxy2"] où "proxy2" est le plus en aval.

Il est à noter que, selon ma compréhension, Express req.ip est une meilleure approche que req.connection.remoteAddress, car req.ip contient l'adresse IP du client réel (à condition que le proxy sécurisé soit activé dans express), Si il y en a un). 

C’est la raison pour laquelle la réponse actuellement acceptée suggère:

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

Le req.headers['x-forwarded-for'] sera l'équivalent d'Express req.ip.

26
Edwin Dalorzo
  1. Ajouter app.set('trust proxy', true)
  2. Utilisez req.ip ou req.ips de la manière habituelle
4
Bald

Selon Express behind proxies , req.ip a pris en compte le proxy inverse si vous avez correctement configuré trust proxy. Par conséquent, il vaut mieux que req.connection.remoteAddress obtenu à partir de la couche réseau et ignorant le proxy.

3
abbr

L'objet en-têtes a tout ce dont vous avez besoin, procédez comme suit: 

var ip = req.headers['x-forwarded-for'].split(',')[0];
1
Juan David Arce

Cela a fonctionné pour moi mieux que le reste. Mes sites sont derrière CloudFlare et cela semblait nécessiter cf-connecting-ip

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

N'a pas testé Express derrière les proxies car il n'a rien dit sur cet en-tête cf-connecting-ip.

1
ile

Utilisez simplement ce middleware express https://www.npmjs.com/package/express-ip

Vous pouvez installer le module en utilisant 

npm i express-ip

Usage

const express = require('express');
const app = express();
const expressip = require('express-ip');
app.use(expressip().getIpInfoMiddleware);

app.get('/', function (req, res) {
    console.log(req.ipInfo);
});
1
Oyetoke Tobi

Ceci est juste des informations supplémentaires pour cette réponse .

Si vous utilisez nginx, vous ajouteriez proxy_set_header X-Real-IP $remote_addr; au bloc d’emplacement du site. /etc/nginx/sites-available/www.example.com par exemple. Voici un exemple de bloc serveur.

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

    location / {
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_pass http://127.0.1.1:3080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $Host;
        proxy_cache_bypass $http_upgrade;
    }
}

Après avoir redémarré nginx, vous pourrez accéder à l'ip dans vos routes d'application node/express avec req.headers['x-real-ip'] || req.connection.remoteAddress;

1
learnsomemore

var ip = req.connection.remoteAddress;

ip = ip.split (':') [3];

0
Bhulawat Ajay

Avec le support de pourrais-flare, nginx et x-real-ip

var user_ip;

    if(req.headers['cf-connecting-ip'] && req.headers['cf-connecting-ip'].split(', ').length) {
      let first = req.headers['cf-connecting-ip'].split(', ');
      user_ip = first[0];
    } else {
      let user_ip = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
    }
0
kakopappa

Je sais que cette question a reçu une réponse, mais voici comment j'ai réussi à faire fonctionner la mienne.

let ip = req.connection.remoteAddress.split(`:`).pop();
0
Lorem Ipsum