首页 文章

Express.js:如何获取远程客户端地址

提问于
浏览
173

我不完全理解我应该如何获得远程用户IP地址 .

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

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

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

上述方法是否正确以获取真实的用户IP地址还是有更好的方法?那些代理呢?

10 回答

  • 46

    如果您在像NGiNX这样的代理服务器后面运行,或者您拥有什么,那么您应该检查'x-forwarded-for':

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

    如果代理不是'你的',我不会相信'x-forwarded-for' Headers ,因为它可能是欺骗性的 .

  • 1

    虽然@alessioalex的答案有效,但还有另一种方法,如Express - guide的代理后快速部分所述 .

    • app.enable('trust proxy') 添加到您的快速初始化代码中 .

    • 如果要获取远程客户端的IP,请以通常的方式使用 req.ipreq.ips (就好像没有反向代理)

    如果您需要比信任x-forwarded-for标头中传递的所有内容更复杂的东西,并且您的代理不会从不受信任的来源中删除预先存在的x-forwarded-for标头,则可以使用更多“信任代理”选项 . 有关详细信息,请参阅链接指南 .

    注意: req.connection.remoteAddress 不适用于我的解决方案 .

  • 0

    nginx.conf 文件中:
    proxy_set_header X-Real-IP $remote_addr;

    node.js 服务器文件中:
    var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;

    请注意,表示小写 Headers

  • 4

    特别是对于节点,http服务器组件的文档,在event connection下面说:

    [Triggered] Build 新的TCP流时 . [socket]是net.Socket类型的对象 . 通常用户不希望访问此事件 . 特别是,由于协议解析器如何附加到套接字,套接字将不会发出可读事件 . 也可以在request.connection上访问套接字 .

    所以,这意味着 request.connection 是一个套接字,根据文档确实有socket.remoteAddress属性,根据文档是:

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

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

    但是,在Express.js下,请求已经有两个属性:req.ipreq.ips

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

    值得一提的是,根据我的理解,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 .

  • 26
    • 添加 app.set('trust proxy', true)

    • 以通常的方式使用 req.ipreq.ips

  • 175

    根据Express behind proxies,如果您已正确配置 trust proxyreq.ip 已考虑反向代理 . 因此,它优于 req.connection.remoteAddress ,它是从网络层获得的,并且不知道代理 .

  • -2

    这对我来说比其他人更好 . 我的网站支持CloudFlare,似乎需要 cf-connecting-ip .

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

    没有测试Express behind proxies因为它没有对这个 cf-connecting-ip Headers 说什么 .

  • 1

    header对象包含您需要的所有内容,只需执行以下操作:

    var ip = req.headers['x-forwarded-for'].split(',')[0];
    
  • 3

    var ip = req.connection.remoteAddress;

    ip = ip.split(':')[3];

  • 339

    只需使用这个快速中间件https://www.npmjs.com/package/express-ip

    您可以使用安装模块

    npm i express-ip
    

    用法

    const express = require('express');
    const app = express();
    const expressip = require('express-ip');
    app.use(expressip().getIpInfoMiddleware);
    
    app.get('/', function (req, res) {
        console.log(req.ipInfo);
    });
    

相关问题