如何获取Meteor服务器中的用户IP地址?

时间:2013-02-12 22:41:16

标签: meteor

我想在服务器端的meteor应用程序中获取用户IP地址,这样我就可以用一堆东西记录IP地址(例如:订阅邮件列表的非注册用户,或者只做重要)。

我知道当涉及反向代理时,服务器“看到”的IP地址可能与实际源地址不同。在这种情况下,应解析X-Forwarded-For标头以获取用户的真实公共IP地址。请注意,解析X-Forwarded-For不应该是自动的(有关潜在安全问题的讨论,请参阅http://www.openinfo.co.uk/apache/index.html)。

外部参考:meteor-talk mailing list in august 2012提出了这个问题(没有提供解决方案)。

6 个答案:

答案 0 :(得分:30)

1 - 如果没有http请求,您应该可以在函数中获取clientIP:

clientIP = this.connection.clientAddress;
//EX: you declare a submitForm function with Meteor.methods and 
//you call it from the client with Meteor.call().
//In submitForm function you will have access to the client address as above

2 - 使用http请求并使用iron-router及其Router.map函数:

在目标路线的动作功能中使用:

clientIp = this.request.connection.remoteAddress;

3 - 使用Meteor.onConnection功能:

Meteor.onConnection(function(conn) {
    console.log(conn.clientAddress);
});

答案 1 :(得分:2)

类似于TimDog的答案,但适用于较新版本的Meteor:

var Fiber = Npm.require('fibers');

__meteor_bootstrap__.app
  .use(function(req, res, next) {
    Fiber(function () {
      console.info(req.connection.remoteAddress);
      next();
    }).run();
  });

这需要在您的顶级服务器代码中(不在Meteor.startup中)

答案 2 :(得分:2)

这个答案https://stackoverflow.com/a/22657421/2845061已经很好地展示了如何获取客户端IP地址。

我只想注意如果您的应用是在代理服务器后面提供(通常会发生),则需要将 HTTP_FORWARDED_COUNT 环境变量设置为您正在使用的代理数量。

参考:https://docs.meteor.com/api/connections.html#Meteor-onConnection

答案 3 :(得分:1)

您可以在服务器代码中执行此操作:

Meteor.userIPMap = [];
__meteor_bootstrap__.app.on("request", function(req, res) {
    var uid = Meteor.userId();
    if (!uid) uid = "anonymous";
    if (!_.any(Meteor.userIPMap, function(m) { m.userid === uid; })) {
        Meteor.userIPMap.push({userid: uid, ip: req.connection.remoteAddress });
    }
});

然后,您将拥有一个Meteor.userIPMap,其中包含用户ID到IP地址的映射(以容纳上面的x-forwarded-for标头,use this function。)

三个注释:(1)只要您的应用中有请求,就会触发,因此我不确定这会导致什么样的性能影响; (2)__meteor_bootstrap__对象即将消失我认为即将推出的改进包裹系统; (3)anonymous用户需要在这里更好地处理..你需要一种方法通过请求对象中唯一的持久约束将匿名用户附加到IP。

答案 4 :(得分:1)

您必须挂钩服务器会话并获取当前用户的IP:

Meteor.userIP = function(uid) {
      var k, ret, s, ss, _ref, _ref1, _ref2, _ref3;
      ret = {};
      if (uid != null) {
            _ref = Meteor.default_server.sessions;
            for (k in _ref) {
                  ss = _ref[k];
                  if (ss.userId === uid) {
                        s = ss;
                  }
            }
            if (s) {
                  ret.forwardedFor = ( _ref1 = s.socket) != null ? 
                        ( _ref2 = _ref1.headers) != null ? 
                        _ref2['x-forwarded-for'] : void 0 : void 0;
                  ret.remoteAddress = ( _ref3 = s.socket) != null ? 
                        _ref3.remoteAddress : void 0;
            }
      }
      return ret.forwardedFor ? ret.forwardedFor : ret.remoteAddress;
};

当然,您需要当前用户才能登录。如果您需要匿名用户,请按照this post编写。

P.S。我知道它是一个旧线程,但它没有完整的答案,或者代码不再有效。

答案 5 :(得分:1)

这是一种方法,可以帮助我从服务器上的任何位置获取客户端的IP地址,而无需使用其他软件包。在Meteor 0.7中工作,也应该在早期版本中工作。

在客户端上,获取套接字URL(唯一)并将其发送到服务器。您可以在Web控制台中查看套接字URL(在Chrome和Safari中的网络下)。

socket_url = Meteor.default_connection._stream.socket._transport.url
Meteor.call('clientIP', socket_url)

然后,在服务器上,使用客户端的套接字URL在Meteor.server.sessions中查找其IP。

sr = socket_url.split('/')
socket_path = "/"+sr[sr.length-4]+"/"+sr[sr.length-3]+"/"+sr[sr.length-2]+"/"+sr[sr.length-1]
_.each(_.values(Meteor.server.sessions), (session) ->
    if session.socket.url == socket_path
        user_ip = session.socket.remoteAddress
)

user_ip现在包含已连接客户端的IP地址。