6

I recently hosted my first Node app using Express and socket.io on Heroku and need to find the client's IP address. So far I've tried socket.manager.handshaken[socket.id].address, socket.handshake.address and socket.connection.address , neither of which give the correct address.

App: http://nes-chat.herokuapp.com/ (also contains a link to GitHub repo)

To view IPs of connected users: http://nes-chat.herokuapp.com/users

Anyone know what the problem is?

Douglas
  • 83
  • 1
  • 2
  • 5
  • Related : http://stackoverflow.com/questions/6458083/socket-io-get-clients-ip-address – nha Oct 13 '14 at 20:01

3 Answers3

12

The client IP address is passed in the X-Forwarded-For HTTP header. I haven't tested, but it looks like socket.io already takes this into account when determining the client IP.

You should also be able to just grab it yourself, here's a guide:

function getClientIp(req) {
  var ipAddress;
  // Amazon EC2 / Heroku workaround to get real client IP
  var forwardedIpsStr = req.header('x-forwarded-for'); 
  if (forwardedIpsStr) {
    // 'x-forwarded-for' header may return multiple IP addresses in
    // the format: "client IP, proxy 1 IP, proxy 2 IP" so take the
    // the first one
    var forwardedIps = forwardedIpsStr.split(',');
    ipAddress = forwardedIps[0];
  }
  if (!ipAddress) {
    // Ensure getting client IP address still works in
    // development environment
    ipAddress = req.connection.remoteAddress;
  }
  return ipAddress;
};
friism
  • 19,068
  • 5
  • 80
  • 116
  • 1
    Here it says why just taking the first one can be dangerous: http://esd.io/blog/flask-apps-heroku-real-ip-spoofing.html (The value can be manipulated.) – caw Aug 16 '13 at 00:53
  • 1
    The pull request in that was never accepted into socket.io. – SystemParadox Dec 19 '14 at 14:51
  • Thanks for this! I'm using SocketIO v1.4.5 and I had to change the lookup to `req.headers['x-forwarded-for']` and also check `if (forwardedIpsStr && forwardedIpsStr !== undefined)` for it to work properly for me. – Joe P Mar 06 '16 at 18:22
5

You can do it in one line.

function getClientIp(req) {
    // The X-Forwarded-For request header helps you identify the IP address of a client when you use HTTP/HTTPS load balancer.
    // http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#x-forwarded-for
    // If the value were "client, proxy1, proxy2" you would receive the array ["client", "proxy1", "proxy2"]
    // http://expressjs.com/4x/api.html#req.ips
    var ip = req.headers['x-forwarded-for'] ? req.headers['x-forwarded-for'].split(',')[0] : req.connection.remoteAddress;
    console.log('IP: ', ip);
}

I like to add this to middleware and attach the IP to the request as my own custom object.

Bernie Perez
  • 12,513
  • 13
  • 46
  • 55
1

The below worked for me.

Var client = require('socket.io').listen(8080).sockets;

client.on('connection',function(socket){ 
var clientIpAddress= socket.request.socket.remoteAddress;
});
Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
VoidA313
  • 516
  • 3
  • 10