27

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

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

外部参考:这个问题出现在 2012 年 8 月的流星谈话邮件列表中(没有提供解决方案)。

4

6 回答 6

34

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);
});
于 2014-03-26T10:02:35.123 回答
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 中)

于 2013-06-13T03:07:03.240 回答
2

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

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

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

于 2016-12-04T03:07:26.717 回答
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 标头,请在上面使用此函数)。

三个注意事项:(1)每当您的应用程序中有请求时,它都会触发,所以我不确定这会导致什么样的性能损失;(2)__meteor_bootstrap__我认为随着即将改进的包装系统,该对象很快就会消失;(3)anonymous用户需要在这里更好地处理..您需要一种方法,通过其请求对象中的唯一、持久约束将匿名用户附加到 IP。

于 2013-02-13T01:02:22.733 回答
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;
};

当然,您需要当前用户登录。如果您需要匿名用户,请按照我写的这篇文章。

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

于 2013-08-19T13:17:50.390 回答
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.

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 地址。

于 2014-03-03T18:50:16.723 回答