35

req.connection.remoteAddress, req.headers['x-forwarded-for'], req.ip, req.ips, what does it all mean?

Is there a straight forward way to simply get the IP address of the client/user-agent making the request to my site in Node.js/Express? I'm not understanding all the proxy stuff or what all the differences between all the properties of the req object. Also, I don't understand what the 'trust proxy' option is for Express.

Could someone give me a straight forward explanation to what the difference is between all of these properties, and answer how I can just simply get the client's IP?

Sam
  • 6,414
  • 11
  • 46
  • 61
  • How about using **[node-ipware](https://github.com/un33k/node-ipware)** as per the explanation **[here](http://stackoverflow.com/a/26310355/458879)**. – Val Neekman Nov 03 '14 at 02:33

5 Answers5

62

req.ip is the straightforward way to get the client's IP address in Express. You can see the logic it uses (which involves grabbing the first item from the array of proxy addresses req.ips, where that array is constructed from the x-forwarded-for headers) here.

Binoy Babu
  • 16,699
  • 17
  • 91
  • 134
Dan Kohn
  • 33,811
  • 9
  • 84
  • 100
21
// Get client IP address from request object ----------------------
getClientAddress = function (req) {
        return (req.headers['x-forwarded-for'] || '').split(',')[0] 
        || req.connection.remoteAddress;
};
Svbaker
  • 706
  • 3
  • 4
  • And what does `req` object holds, I mean what shall we be providing there? – Sanjay Mar 02 '15 at 05:29
  • 3
    Note that `req.headers['x-forwarded-for']` is easily manipulated at the PC unless you have placed your Node.JS server behind a trusted and properly configured proxy server. You should first check `req.connection.remoteAddress` against a list of known trustable proxy servers before respecting `req.headers['x-forwarded-for']`. – 700 Software Sep 22 '15 at 01:44
  • Appreciate the OR and split additions. This is good if you have your app behind both a load balancer and/or a caching layer. – justinpage May 18 '16 at 06:33
  • 5
    its returning `::ffff:127.0.0.1` for the first hit and for every later hit it returns `::1`. Both are not the proper public IPs and not able to fetch location out of them. Help me resolve this. Thanking You! – Dynamic Remo Apr 13 '17 at 16:16
  • For 2021, for node.js without express, its still answer! Upload that to hosting to make it work correctly. Thanks! – Mr.Fingers Mar 14 '21 at 20:10
5

As other's have noted, due to the use potential use of proxies, you really should use req.ip and NOT use the X-Forwarded-For header like so many people are recommending. As long as you properly configure a proxy as a trusted proxy, req.ip will always return the end-user's IP address.

e.g. If you had a proxy that was connecting from 8.8.8.8, you'd do:

var express = require('express');
var app = express();
app.set('trust proxy', '8.8.8.8');

Since you trust the proxy, this would now make it so what is passed in the X-Forwarded-For header will be stored in req.ip, but ONLY if it originates from one of the trusted proxies.

More on trust proxy can be found here.

Now, as others have noted in the comments; especially when developing locally you may get the ip in the format of "::ffff:127.0.0.1".

To always get the IPv4 Address I have:

getClientAddress = function (req) {
    return req.ip.split(":").pop();
};
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
Doug
  • 6,446
  • 9
  • 74
  • 107
4

very simple

function getClientIP(req){
    return req.headers['x-forwarded-for'] || req.connection.remoteAddress;
}
Behnam
  • 6,244
  • 1
  • 39
  • 36
  • 1
    Hi, I have placed `app.enable('trust proxy');` in my server.ts file right after my following code `import { serverApi, createTodoApi } from './backend/api'; app.get('/data.json', serverApi); app.use('/api', createTodoApi());` and accessing the variables `req.ip` in my backend/api.ts file. Where its returning `::ffff:127.0.0.1`, which is not a valid ip address to fetch the location out of it. Waiting for your response. Thanks! – Dynamic Remo Apr 13 '17 at 16:54
  • I also had the `ffff` initially when tested locally. While it's easy to parse, I opted to set the server to listen only to IPv4 (I have a proxy anyway), based on [this answer](https://stackoverflow.com/a/48170565/5362795) and that gives me a clean IPv4 on `remoteAddress`. – Nagev May 06 '22 at 08:47
0

Getting the client IP is pretty straightforward:

 var ip = req.headers['x-forwarded-for'] || 
     req.connection.remoteAddress || 
     req.socket.remoteAddress ||
     req.connection.socket.remoteAddress;
     console.log(ip);
Garistar
  • 363
  • 3
  • 8
  • 1
    Note that `req.headers['x-forwarded-for']` is easily manipulated at the PC unless you have placed your Node.JS server behind a trusted and properly configured proxy server. You should first check `req.connection.remoteAddress` against a list of known trustable proxy servers before respecting `req.headers['x-forwarded-for']`. If there are multiple proxies involved, then `req.headers['x-forwarded-for']` may contain a comma separated list. – 700 Software Sep 22 '15 at 01:43