Express.js:如何获取远程客户端地址
我不完全了解如何获得远程用户IP地址。
比方说,我有一个简单的请求路线,如:
app.get(/, function (req, res){ var forwardedIpsStr = req.header('x-forwarded-for'); var IP = ''; if (forwardedIpsStr) { IP = forwardedIps = forwardedIpsStr.split(',')[0]; } });
上面的方法是否正确得到真正的用户IP地址还是有更好的办法? 那么代理呢?
如果你在NGiNX之类的代理之后运行,那么你应该检查'x-forwarded-for':
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
如果代理不是'你的',我不会相信'x-forwarded-for'标题,因为它可能被欺骗。
虽然@alessioalex的答案是有效的,但快递指南的 代理部分后面还有另一种方法。
- 将
app.enable('trust proxy')
到您的快速初始化代码。 - 当你想获得远程客户端的IP地址时,以通常的方式使用
req.ip
或req.ips
(就好像没有反向代理一样)
如果您需要比信任x-forwarded-for标头中所有内容更复杂的东西,并且代理不会从不受信任的来源中移除预先存在的x-forwarded-for标头,那么可以使用“信任代理”的更多选项。 有关更多详细信息,请参阅链接指南
注意: req.connection.remoteAddress
不适用于我的解决scheme。
在nginx.conf
文件中:
proxy_set_header X-Real-IP $remote_addr;
在node.js
服务器文件中:
var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
注意,表示小写标题
特别是对于节点,HTTP服务器组件的文档,在事件连接下说:
当一个新的TCPstreambuild立时触发。 [socket]是net.Sockettypes的对象。 通常用户不会想要访问这个事件。 特别是,由于协议parsing器如何连接到套接字,套接字将不会发出可读的事件。 套接字也可以通过
request.connection
访问。
所以,这意味着request.connection
是一个套接字,根据文档确实有一个socket.remoteAddress属性,根据文档是:
远程IP地址的string表示。 例如,“74 .125.127.100”或“2001:4860:a005 :: 68”。
在express下,请求对象也是Node http请求对象的一个实例,所以这种方法应该仍然有效。
但是,在Express.js下,请求已经有两个属性: req.ip和req.ips
req.ip
返回远程地址,或当“信任代理”启用 – 上游地址。
req.ips
当“信任代理”为
true
,parsing“X-Forwarded-For”IP地址列表并返回一个数组,否则返回一个空数组。 例如,如果值为“client,proxy1,proxy2”,您将收到数组[“client”,“proxy1”,“proxy2”],其中“proxy2”是最下游的数据stream。
值得一提的是,根据我的理解,Express req.ip
是比req.connection.remoteAddress
更好的方法,因为req.ip
包含实际的客户端ip(假设在express中启用了可信代理),而其他可能包含代理的IP地址(如果有的话)。
这就是为什么目前接受的答案表明:
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
req.headers['x-forwarded-for']
将等同于express req.ip
根据Express后面的代理 , req.ip
已经考虑了反向代理,如果你已经正确configurationtrust proxy
。 因此,它比从networking层获得并且不知道代理的req.connection.remoteAddress
要好。
- 添加
app.set('trust proxy', true)
- 以通常的方式使用
req.ip
或req.ips
这对我来说比其他的更好。 我的网站在CloudFlare的后面,似乎需要cf-connecting-ip
。
req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress
没有testingExpress后面的代理,因为它没有说这个cf-connecting-ip
头。