2013-02-12 2 views
25

Ich möchte die Benutzer-IP-Adresse in meiner Meteor-Anwendung, auf der Server-Seite, so dass ich die IP-Adresse mit einer Reihe von Dingen protokollieren kann (zum Beispiel: nicht registrierte Benutzer eine Mailing-Liste abonnieren, oder einfach etwas tun wichtig).Wie bekomme ich die Benutzer-IP-Adresse in Meteor Server?

Ich weiß, dass die vom Server 'gesehene' IP-Adresse von der realen Quelladresse abweichen kann, wenn Reverse-Proxies beteiligt sind. In solchen Situationen sollte X-Forwarded-For Header geparst werden, um die echte öffentliche IP-Adresse des Benutzers zu erhalten. Beachten Sie, dass das Parsen X-Forwarded-For nicht automatisch sein sollte (siehe http://www.openinfo.co.uk/apache/index.html für eine Diskussion über mögliche Sicherheitsprobleme).

Externe Referenz: Diese Frage kam auf die meteor-talk mailing list in august 2012 (keine Lösung angeboten).

+0

Die kanonische Antwort ist auf [verwenden, um die Benutzer-Status Paket] (http://stackoverflow.com/questions/18507998/how-to-access-client-ip-address-in- Meteor/24060277 # 24060277). –

Antwort

28

1 - Ohne eine HTTP-Anforderung, in den Funktionen sollten Sie in der Lage sein, die ClientIP zu bekommen mit:

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 - Mit einer HTTP-Anforderung und Verwendung von Eisen-Router und seine Router.map Funktion:

In der Aktion Funktion der gezielten Route Verwendung:

clientIp = this.request.connection.remoteAddress; 

3 - mit Meteor.onConnection Funktion:

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

Sieht neu und aufregend aus. Weißt du, wann das zu Meteor hinzugefügt wurde? – sarfata

+0

Ich weiß nicht, wann der erste hinzugefügt wurde. Leider ist mein zweites Beispiel Express, aber es kann ähnlich mit Iron-Router gemacht werden und in der Action-Funktion können Sie this.connection.clientAddress oder this.request.connection verwenden.Clientadresse; Ich werde meinen Beitrag so schnell wie möglich aktualisieren. –

+0

Ich habe meine Antwort bearbeitet und die Expressjs-Lösung durch die mit dem neuesten Router für Meteor ersetzt. –

1

Sie können diesen Code in Ihrem Server tun:

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

Sie werden dann mit einer Karte von Benutzer-IDs ein Meteor.userIPMap müssen IP-Adressen (um die x-forwarded-for-Header aufnehmen, use this function innen obenstehendes).

Drei Anmerkungen: (1) Dies wird ausgelöst, wenn eine Anfrage in Ihrer App vorhanden ist, also bin ich mir nicht sicher, welche Art von Leistung dies verursacht; (2) das Objekt __meteor_bootstrap__ geht bald weg Ich denke mit einem bevorstehenden überarbeiteten Paketsystem; und (3) der anonymous Benutzer benötigt hier eine bessere Handhabung. Sie benötigen einen Weg, um einen anonymen Benutzer an eine IP durch eine eindeutige persistente Einschränkung in ihrem Anfrageobjekt anzuhängen.

+0

Sieht nach einer sehr einfachen und coolen Lösung aus: Ich dachte, ich würde ein Atmosphärenpaket nur dafür schreiben. Vielen Dank, ich werde bald testen! – sarfata

+0

Leider funktioniert es nicht (Meteor 0,5,9): "Fehler: Meteor Code muss immer innerhalb einer Fiber laufen" - Das Problem ist in Meteor.userId(). - Das ist ein Mist, ich mochte deine Idee wirklich. – sarfata

2

ähnlich die TimDog Antwort, sondern arbeitet mit neueren Versionen von Meteor:

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

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

Dies muss in der Top-Level-Server-Code sein (nicht in Meteor.startup)

+0

Wie verknüpfst du das mit einem Meteor.user? – Swadq

+0

Danke für den Beitrag. Es bekommt eine IP-Adresse, aber ich bekomme immer 127.0.0.1 - ich denke, das liegt daran, dass Meteor eine erste Instanz mit einem HTTP-Proxy startet, der die Anfrage an die zweite Instanz weiterleitet. Die eingehende Anfrage wird immer 127.0.0.1 sein. – sarfata

+0

Zum Glück für uns - der HTTP-Proxy leitet die eingehende IP-Adresse so, dass wir etwas tun können: console.info (req.headers ['x-forwarded-for']); - Allerdings kann ich das noch nicht mit dem aktuellen Benutzer verknüpfen, da die Meteor.userId() nicht direkt aufgerufen werden kann (Fehler: Meteor.userId kann nur in Methodenaufrufen aufgerufen werden. Verwenden Sie this.userId in Veröffentlichungsfunktionen.). Irgendwelche Ideen? – sarfata

1

Sie müssen Haken in die Server-Sitzungen und die IP des aktuellen Benutzers greifen.

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

natürlich können Sie den aktuellen Benutzer müssen angemeldet sein, wenn Sie es für anonyme Benutzer müssen auch folgen this post Ich schrieb.

P.S. Ich weiß, es ist ein alter Thread, aber es fehlte eine vollständige Antwort oder hatte Code, der nicht mehr funktioniert.

+0

Sehr bedauerlich, dass ich Ihren Beitrag nicht früher erwogen oder beantwortet habe. Der Link, den du geteilt hast, ist jetzt ein 404. Könnten Sie es aktualisieren? Wenn es auch für anonyme Benutzer funktioniert, würde ich gerne Ihre Antworten als die richtige bestätigen! – sarfata

1

Hier ist ein Weg, der für mich funktioniert, um die IP-Adresse eines Clients von überall auf dem Server zu erhalten, ohne zusätzliche Pakete zu verwenden. Arbeitet in Meteor 0.7 und sollte auch in früheren Versionen funktionieren.

Auf dem Client, erhalten Sie die Socket-URL (eindeutig) und senden Sie es an den Server. Sie können die Socket-URL in der Webkonsole anzeigen (unter Netzwerk in Chrome und Safari).

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

Dann auf dem Server, verwenden Sie das Socket-URL des Clients ihre IP in Meteor.server.sessions zu finden.

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 enthält nun die IP-Adresse des angeschlossenen Clients.

+0

Das funktioniert, aber verlassen sich auf den Client zu finden, die IP ist nicht gut genug, wenn Sie versuchen, die IP-Adresse für Sicherheitszwecke zu verwenden. Es ist zu leicht zu fälschen. Der Benutzer könnte einfach die Konsole öffnen und Meteor.call ('whatever IP') aufrufen. – sarfata

+1

Nun, es ist nicht so einfach zu fälschen, weil Sie "Meteor.server.sessions" für die korrekte SockJS URL überprüfen, die Ihnen vom Client gesendet wird. (SockJS-URLs sind eindeutig, z. B. '/ sockjs/580/uqafmf0o'). Wenn Sie die vom Client an Sie gesendete URL nicht finden, wissen Sie, dass sie sie gefälscht hat, sodass Sie einen Fehler zurückgeben. Ich bin mir nicht sicher, was Sie mit Ihrem Kommentar oben meinen, aber der Client sendet dem Server nicht seine IP im obigen Code. – alste