我不完全明白我应该如何获得一个远程用户IP地址。

假设我有一个简单的请求路由,如:

app.get(/, function (req, res){
   var forwardedIpsStr = req.header('x-forwarded-for');
   var IP = '';

   if (forwardedIpsStr) {
      IP = forwardedIps = forwardedIpsStr.split(',')[0];  
   }
});

上面的方法是否正确,以获得真实的用户IP地址或有更好的方法? 那么代理呢?


当前回答

如果你很好使用第三方库。可以检查request-ip。

你可以用is by

import requestIp from 'request-ip';

app.use(requestIp.mw())

app.use((req, res) => {
  const ip = req.clientIp;
});

源代码很长,所以我就不复制了,你可以在https://github.com/pbojinov/request-ip/blob/master/src/index.js上查看

基本上,

It looks for specific headers in the request and falls back to some defaults if they do not exist. The user ip is determined by the following order: X-Client-IP X-Forwarded-For (Header may return multiple IP addresses in the format: "client IP, proxy 1 IP, proxy 2 IP", so we take the the first one.) CF-Connecting-IP (Cloudflare) Fastly-Client-Ip (Fastly CDN and Firebase hosting header when forwared to a cloud function) True-Client-Ip (Akamai and Cloudflare) X-Real-IP (Nginx proxy/FastCGI) X-Cluster-Client-IP (Rackspace LB, Riverbed Stingray) X-Forwarded, Forwarded-For and Forwarded (Variations of #2) req.connection.remoteAddress req.socket.remoteAddress req.connection.socket.remoteAddress req.info.remoteAddress If an IP address cannot be found, it will return null.

公开:我和图书馆没有关系。

其他回答

根据快递背后的代理,要求。如果正确配置了信任代理,则IP已考虑反向代理。因此,它比req.connection.remoteAddress要好,因为req.connection.remoteAddress是从网络层获取的,不需要代理。

这对我来说比其他方法更有效。我的网站在CloudFlare后面,它似乎需要cf- connection -ip。

req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress

没有测试代理后面的Express,因为它没有说任何关于这个cf- connection -ip头。

特别是对于node, http server组件的文档,在事件连接下说:

建立新的TCP流时触发。套接字是类型对象 net.Socket。通常用户不会想要访问这个事件。在 特别是,套接字将不会发出可读的事件,因为如何 协议解析器附加到套接字。插座也可以 通过request.connection访问。

这意味着请求。连接是一个套接字,根据文档,确实有一个套接字。根据文档,remoteAddress属性为:

远程IP地址的字符串表示形式。例如, '74.125.127.100'或'2001:4860:a005::68'。

在express下,请求对象也是Node http请求对象的一个实例,因此这种方法仍然有效。

然而,在Express.js下,请求已经有两个属性:req。IP和req.ips

req.ip 返回远程地址,或者当启用“信任代理”时返回上游地址。 req.ips 当“trust proxy”为true时,解析“X-Forwarded-For”ip地址列表并返回一个数组,否则为空数组 返回。例如,如果值是“client, proxy1, proxy2” 将接收数组["client", "proxy1", "proxy2"],其中"proxy2" 是下游最远的地方。

值得一提的是,根据我的理解,特快要求。IP是比req.connection更好的方法。remoteAddress, since req。ip包含实际的客户端ip(前提是在express中启用了可信代理),而另一个可能包含代理的ip地址(如果有的话)。

这就是为什么目前公认的答案是:

Var IP = req。标题(“x-forwarded-for”)| | req.connection.remoteAddress;

要求的事情。Headers ['x-forwarded-for']将等价于express req.ip。

如果你很好使用第三方库。可以检查request-ip。

你可以用is by

import requestIp from 'request-ip';

app.use(requestIp.mw())

app.use((req, res) => {
  const ip = req.clientIp;
});

源代码很长,所以我就不复制了,你可以在https://github.com/pbojinov/request-ip/blob/master/src/index.js上查看

基本上,

It looks for specific headers in the request and falls back to some defaults if they do not exist. The user ip is determined by the following order: X-Client-IP X-Forwarded-For (Header may return multiple IP addresses in the format: "client IP, proxy 1 IP, proxy 2 IP", so we take the the first one.) CF-Connecting-IP (Cloudflare) Fastly-Client-Ip (Fastly CDN and Firebase hosting header when forwared to a cloud function) True-Client-Ip (Akamai and Cloudflare) X-Real-IP (Nginx proxy/FastCGI) X-Cluster-Client-IP (Rackspace LB, Riverbed Stingray) X-Forwarded, Forwarded-For and Forwarded (Variations of #2) req.connection.remoteAddress req.socket.remoteAddress req.connection.socket.remoteAddress req.info.remoteAddress If an IP address cannot be found, it will return null.

公开:我和图书馆没有关系。

在我的案例中,类似于这个解决方案,我最终使用了以下x-forward for方法:

let ip = (req.headers['x-forwarded-for'] || '').split(',')[0];

x-forward -for报头将继续添加从源服务器到最终目标服务器的IP路由,因此如果需要检索源客户端的IP,这将是数组的第一项。