Nodejs distinguishing http requests; multiple devi

2019-08-03 05:57发布

问题:

Нello! I'm trying to represent client connections over http with node. Right now I have something like:

let names = [ 'john', 'margaret', 'thompson', /* ... tons more ... */ ];
let nextNameInd = 0;   

let clientsIndexedByIp = {};
let createNewClient = ip => {
  return {
    ip,
    name: names[nextNameInd++],
    numRequests: 0
  };
};

require('http').createServer((req, res) => {

  let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

  // If this is a connection we've never seen before, create a client for it
  if (!clientsIndexedByIp.hasOwnProperty(ip)) {
    clientsIndexedByIp[ip] = createNewClient(ip);
  }

  let client = clientsIndexedByIp[ip];
  client.numRequests++;

  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify(client));

}).listen(80, '<my public ip>', 511);

I run this code on some remote server and it works fine; I can query that server and get the expected response. But I have an issue: my laptop and my smartphone are both connected to the same wifi; if I query that server from both my laptop and smartphone the server thinks that both devices have the same IP address and it only creates one "client" object for the both of them.

E.g. the "name" parameter of the response is the same for each.

Checking whatsmyip.org on both my laptop and smartphone shows me the same IP address - this surprised me, as my understanding of IPs turned out to be wrong. Until this point I thought all devices had a unique IP.

I want different devices to become associated with different clients, even when two devices are on the same wifi network. I assume that the data I'm using to disambiguate devices, their request IP alone (req.headers['x-forwarded-for'] || req.connection.remoteAddress), is insufficient.

How can I differentiate between multiple devices connected to the same router? Is there some extra bit of data in the req object which allows for this?

Or is it just a case of network misconfiguration that both my laptop and smartphone have the same IP address?

Thanks!

回答1:

If you use the express-fingerprint module, this will work for most use cases, for example:

const express = require('express');
const app = express();
const port = 3000;
var Fingerprint = require('express-fingerprint')

app.use(Fingerprint( { parameters:[
    Fingerprint.useragent,
    Fingerprint.geoip ]
}));

app.get('/test', function(req, res){
    console.log("Client fingerprint hash: ", req.fingerprint.hash);
    res.send("Your client Id: " + req.fingerprint.hash);
});

app.listen(port);

Each client will have a unique hash you can use to identify them. It's worth understanding that this approach will have limitations and assigning a cookie to the client would work better for some use cases.