如何在托管在Heroku上的Node socket.io应用程序中获取客户端的正确IP地址?

6
最近,我使用Express和socket.io在Heroku上托管了我的第一个Node应用程序,并需要查找客户端的IP地址。目前为止,我尝试了socket.manager.handshaken[socket.id].addresssocket.handshake.addresssocket.connection.address,但都没有给出正确的地址。
应用程序:http://nes-chat.herokuapp.com/(还包含指向GitHub存储库的链接)
要查看连接用户的IP,请访问:http://nes-chat.herokuapp.com/users 请问有谁知道问题是什么?

相关:https://dev59.com/0mw15IYBdhLWcg3wtNuO - nha
3个回答

12

客户端 IP 地址通过 X-Forwarded-For HTTP 头传递。我没有测试过,但是看起来当确定客户端 IP 时,socket.io 已经考虑到了这一点。

你也可以自己获取它,这里有一个指南

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;
};

1
这里解释了为什么仅仅获取第一个值可能是危险的:http://esd.io/blog/flask-apps-heroku-real-ip-spoofing.html (该值可以被篡改)。 - caw
1
那个拉取请求从未被接受到socket.io中。 - SystemParadox
谢谢!我正在使用SocketIO v1.4.5,我不得不将查找更改为req.headers['x-forwarded-for'],并且还要检查if (forwardedIpsStr && forwardedIpsStr !== undefined)以使其对我正常工作。 - Joe P

5
你可以在一行中完成它。
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);
}

我喜欢将这个添加到中间件并将IP附加到请求中作为我的自定义对象。

当我在本地测试时,这总是会导致IP::1的结果? - linus_hologram

1
以下对我有用。
Var client = require('socket.io').listen(8080).sockets;

client.on('connection',function(socket){ 
var clientIpAddress= socket.request.socket.remoteAddress;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接