I have tried all of them didn't work though,
console.log(clientIp);
console.log(req.ip);
console.log(req.headers['x-forwarded-for']);
console.log(req.connection.remoteAddress);
console.log(req.socket.remoteAddress);
console.log(req.connection.socket.remoteAddress.split(",")[0]);
When running an Express app behind a proxy for me Nginx, you have to set the application variable trust proxy to true. Express offers a few other trust proxy values which you can review in their documentation, but below steps worked for me.
app.set('trust proxy', true);
location / { proxy_pass http://localhost:3001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; # this line proxy_cache_bypass $http_upgrade; }
module.exports = function(req, res, next) { let enable = true; // true/false let blacklist = ['x.x.x.x']; let whitelist = ['x.x.x.x']; let clientIp = req.header('x-forwarded-for') || req.connection.remoteAddress; if (!clientIp) { return res.json('Error'); } if (enable && paths.some((path) => (path === req.originalUrl))) { let blacklist = blacklist || []; if (blacklist.some((ip) => clientIp.match(ip) !== null)) { return res.json({ status: 401, error: 'Your IP is black-listed !'}); } let whitelist = whitelist || []; if (whitelist.length === 0 || whitelist.some((ip) => clientIp.match(ip) !== null)) { next(); return; } else { return res.json({ status: 401, error: 'Your IP is not listed !'}); } } next(); };
You can stay DRY and just use node-ipware that supports both IPv4 and IPv6.
Install:
npm install ipware
In your app.js or 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();
});
It will make the best attempt to get the user's IP address or returns 127.0.0.1
to indicate that it could not determine the user's IP address. Take a look at the README file for advanced options.
I'm using express behind nginx and
req.headers.origin
did the trick for me
req.connection
has been deprecated since [email protected]. Using req.connection.removeAddress
to get the client IP might still work but is discouraged.
Luckily, req.socket.remoteAddress
has been there since [email protected] and is a perfect replacement:
The string representation of the remote IP address. For example,
'74.125.127.100'
or'2001:4860:a005::68'
. Value may beundefined
if the socket is destroyed (for example, if the client disconnected).
There are two ways to get the ip address :
let ip = req.ip
let ip = req.connection.remoteAddress;
But there is a problem with above approaches.
If you are running your app behind Nginx or any proxy, every single IP addresses will be 127.0.0.1
.
So, the best solution to get the ip address of user is :-
let ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
request.headers['x-forwarded-for'] || request.connection.remoteAddress
If the x-forwarded-for
header is there then use that, otherwise use the .remoteAddress
property.
The x-forwarded-for
header is added to requests that pass through load balancers (or other types of proxy) set up for HTTP or HTTPS (it's also possible to add this header to requests when balancing at a TCP level using proxy protocol). This is because the request.connection.remoteAddress
the property will contain the private IP address of the load balancer rather than the public IP address of the client. By using an OR statement, in the order above, you check for the existence of an x-forwarded-for
header and use it if it exists otherwise use the request.connection.remoteAddress
.
Following Function has all the cases covered will help
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);
function getCallerIP(request) {_x000D_
var ip = request.headers['x-forwarded-for'] ||_x000D_
request.connection.remoteAddress ||_x000D_
request.socket.remoteAddress ||_x000D_
request.connection.socket.remoteAddress;_x000D_
ip = ip.split(',')[0];_x000D_
ip = ip.split(':').slice(-1); //in case the ip returned in a format: "::ffff:146.xxx.xxx.xxx"_x000D_
return ip;_x000D_
}
_x000D_
var ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
(req.connection.socket ? req.connection.socket.remoteAddress : null);
Note that sometimes you can get more than one IP address in req.headers['x-forwarded-for']
. Also, an x-forwarded-for
header will not always be set which may throw an error.
The general format of the field is:
x-forwarded-for: client, proxy1, proxy2, proxy3
where the value is a comma+space separated list of IP addresses, the left-most being the original client, and each successive proxy that passed the request adding the IP address where it received the request from. In this example, the request passed through proxy1
, proxy2
, and then proxy3
. proxy3
appears as remote address of the request.
This is the solution suggested by Arnav Gupta with a fix Martin has suggested below in the comments for cases when x-forwarded-for
is not set :
var ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress
Suggestion using modern JS:
x-forwarded-for
only if set, if so, take the first addressconst parseIp = (req) =>
(typeof req.headers['x-forwarded-for'] === 'string'
&& req.headers['x-forwarded-for'].split(',').shift())
|| req.connection?.remoteAddress
|| req.socket?.remoteAddress
|| req.connection?.socket?.remoteAddress
console.log(parseIp(req))
// => 127.0.0.1
If you get multiple IPs , this works for me:
var ipaddress = (req.headers['x-forwarded-for'] || _x000D_
req.connection.remoteAddress || _x000D_
req.socket.remoteAddress || _x000D_
req.connection.socket.remoteAddress).split(",")[0];
_x000D_
If you're using express version 3.x or greater, you can use the trust proxy setting (http://expressjs.com/api.html#trust.proxy.options.table) and it will walk the chain of addresses in the x-forwarded-for header and put the latest ip in the chain that you've not configured as a trusted proxy into the ip property on the req object.
Don't just blindly use this for important rate-limiting:
let ip = request.headers['x-forwarded-for'].split(',')[0];
It's very easy to spoof:
curl --header "X-Forwarded-For: 1.2.3.4" "https://example.com"
In that case ther user's real IP address will be:
let ip = request.headers['x-forwarded-for'].split(',')[1];
I'm surprised that no other answers have mentioned this.
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
var ip = req.ip
console.log(ip);
res.send('Hello World!')
})
// Run as nodejs ip.js
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
I realize this has been answered to death, but here's a modern ES6 version I wrote that follows airbnb-base eslint standards.
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;
};
The X-Forwarded-For header may contain a comma-separated list of proxy IPs. The order is client,proxy1,proxy2,...,proxyN. In the real world, people implement proxies that may supply whatever they want in this header. If you are behind a load balancer or something, you can at least trust the first IP in the list is at least whatever proxy some request came through.
Simple get remote ip in nodejs:
var ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
In node 10.14 , behind nginx, you can retrieve the ip by requesting it through nginx header like this:
proxy_set_header X-Real-IP $remote_addr;
Then in your app.js:
app.set('trust proxy', true);
After that, wherever you want it to appear:
var userIp = req.header('X-Real-IP') || req.connection.remoteAddress;
If you are using Graphql-Yoga you can use the following function:
const getRequestIpAddress = (request) => {_x000D_
const requestIpAddress = request.request.headers['X-Forwarded-For'] || request.request.connection.remoteAddress_x000D_
if (!requestIpAddress) return null_x000D_
_x000D_
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]?)")_x000D_
_x000D_
const [ipAddress] = requestIpAddress.match(ipv4)_x000D_
_x000D_
return ipAddress_x000D_
}
_x000D_
You can use request-ip, to retrieve a user's ip address. It handles quite a few of the different edge cases, some of which are mentioned in the other answers.
Disclosure: I created this module
Install:
npm install request-ip
In your app:
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();
};
Hope this helps
Had the same problem...im also new at javascript but i solved this with req.connection.remoteAddress; that gave me th IP address (but in ipv6 format ::ffff.192.168.0.101 ) and then .slice to remove the 7 first digits.
var ip = req.connection.remoteAddress;
if (ip.length < 15)
{
ip = ip;
}
else
{
var nyIP = ip.slice(7);
ip = nyIP;
}
Source: Stackoverflow.com