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

如何在Meteor服务器中获取用户IP地址?,meteor,Meteor,我想在服务器端的meteor应用程序中获取用户IP地址,这样我就可以用很多东西记录IP地址(例如:未注册的用户订阅邮件列表,或者只是做一些重要的事情) 我知道,当涉及反向代理时,服务器“看到”的IP地址可能与实际源地址不同。在这种情况下,应该解析X-Forwarded-For头以获得用户的真实公共IP地址。请注意,解析X-Forwarded-For不应是自动的(有关潜在安全问题的讨论,请参阅) 外部参考:此问题出现在上(未提供解决方案)。您可以在服务器代码中执行此操作: Meteor.userI

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

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


外部参考:此问题出现在上(未提供解决方案)。

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

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标头)


三个注意事项:(1)当你的应用程序中有请求时,这会触发,所以我不确定这会导致什么样的性能下降;(2)
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuMeteor\uuuuubootstrap\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;(3)此处需要更好地处理
匿名用户。。您需要一种方法,通过其请求对象中的唯一、持久约束将匿名用户附加到IP。

类似于TimDog answer,但适用于较新版本的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中)

您必须连接到服务器会话并获取当前用户的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;
};
当然,您需要当前用户才能登录。如果你需要匿名用户也遵循我写的


另外,我知道这是一个旧的线程,但它缺少完整的答案,或者代码不再有效。

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

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

然后,在服务器上,使用客户端的套接字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\u ip
现在包含连接的客户端的ip地址。

1-在没有http请求的情况下,您应该能够使用以下功能获取客户端ip:

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
Meteor.onConnection(function(conn) {
    console.log(conn.clientAddress);
});
2-使用http请求并使用iron路由器及其路由器。映射功能:

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
Meteor.onConnection(function(conn) {
    console.log(conn.clientAddress);
});
在目标路线使用的操作功能中:

clientIp = this.request.connection.remoteAddress;
3-使用Meteor.onConnection函数:

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
Meteor.onConnection(function(conn) {
    console.log(conn.clientAddress);
});
这个答案已经很好地展示了如何获取客户端IP地址

我只想指出,如果您的应用程序是在代理服务器后面提供的(通常发生),则需要将
HTTP\u FORWARDED\u COUNT
环境变量设置为您正在使用的代理数


Ref:

看起来是一个非常简单和酷的解决方案:我以为我要为此编写一个大气包。非常感谢,我马上就要考试了!不幸的是,它不起作用(meteor 0.5.9):“错误:meteor代码必须始终在光纤中运行”-问题出在meteor.userId()中这太糟糕了,我真的很喜欢你的想法。你如何将它链接到Meteor.user?谢谢你的贡献。它得到一个IP地址,但我总是得到127.0.0.1-我想这是因为Meteor使用http代理启动第一个实例,该代理将请求转发给第二个实例。传入的请求总是127.0.0.1。幸运的是,http代理转发传入的ip,这样我们就可以执行如下操作:console.info(req.headers['x-forwarded-for']);-但是,我仍然无法将其链接到当前用户,因为Meteor.userId()无法直接调用(错误:Meteor.userId只能在方法调用中调用。请在发布函数中使用this.userId)。有什么想法吗?有人能想出一个有效的版本吗?我总是得到127.0.0.1作为回应。我在客户端对ipinfo.io这样的服务求助于JSONP请求,这绝对不理想。这是可行的,但当您试图使用IP地址来实现安全目的时,依靠客户端查找IP是不够的。这太容易伪造了。用户只需打开控制台并调用Meteor.call(“任意IP”)。这并不容易伪造,因为您将检查
Meteor.server.sessions
以获取客户端发送给您的正确SockJS URL。(SockJS URL是唯一的,例如
/SockJS/580/uqafmf0o
)。如果您没有找到客户端发送给您的URL,则您知道他们在伪造URL,因此返回一个错误。不确定你上面的评论是什么意思,但是客户没有在上面的代码中发送他们的IP。非常抱歉,我没有考虑或回复你的帖子。您共享的链接现在是404。你能更新一下吗?如果它也适用于匿名用户,我将很高兴确认您的答案是正确的!看起来新的和令人兴奋的。你知道这是什么时候加入流星的吗?不知道第一个是什么时候加入的。不幸的是,我的第二个例子是使用express,但使用iron router也可以进行类似的操作,在操作函数中可以使用this.connection.clientAddress或this.request.connection.clientAddress;我会尽快更新我的帖子。请记住,如果你支持一个代理,这些将不起作用。在这种情况下,您可以尝试类似于
this.connection.httpHeaders['x-real-ip']
或代理添加到数据包中的任何头。在
nginx
Sarfata之后,这对我来说很有效:我认为添加了客户信息。(帽尖指向@Andrew Mao's)。该值现在内置在core中-请参见我在运行nginx代理时的
clientAddress
。我必须设置
proxy\u set\u头X-Forwarded-For$proxy\u a