如何在节点中确定用户的IP地址

时间:2011-11-12 21:56:50

标签: api node.js ip

如何从控制器中确定给定请求的IP地址?例如(明确表示):

app.post('/get/ip/address', function (req, res) {
    // need access to IP address here
})

24 个答案:

答案 0 :(得分:384)

request对象中有一个名为connection的属性,它是一个net.Socket对象。 net.Socket对象具有属性remoteAddress,因此您应该能够通过此调用获取IP:

request.connection.remoteAddress

请参阅httpnet

的文档

修改

正如@juand在评论中指出的那样,如果服务器位于代理之后,获取远程IP的正确方法是request.headers['x-forwarded-for']

答案 1 :(得分:352)

var ip = req.headers['x-forwarded-for'] || 
     req.connection.remoteAddress || 
     req.socket.remoteAddress ||
     (req.connection.socket ? req.connection.socket.remoteAddress : null);

请注意,有时您可以在req.headers['x-forwarded-for']中获得多个IP地址。此外,不会始终设置x-forwarded-for标头,这可能会引发错误。

该字段的一般格式为:

x-forwarded-for: client, proxy1, proxy2, proxy3

其中值是以逗号+空格分隔的IP地址列表,最左边是原始客户端,每个连续的代理通过请求添加接收请求的IP地址。在此示例中,请求通过proxy1proxy2,然后proxy3传递。 proxy3显示为请求的远程地址。

这是Arnav Gupta建议的解决方案,其中针对未设置x-forwarded-for的案例的评论中提出了修正Martin

var ip = (req.headers['x-forwarded-for'] || '').split(',').pop() || 
         req.connection.remoteAddress || 
         req.socket.remoteAddress || 
         req.connection.socket.remoteAddress

答案 2 :(得分:46)

如果使用快递......

req.ip

我正在查看,然后我就像等待,我正在使用快递。咄。

答案 3 :(得分:29)

您可以保持 DRY ,只需使用支持 IPv4 IPv6 node-ipware

安装:

npm install ipware

在您的app.js或中间件中:

var getIP = require('ipware')().get_ip;
app.use(function(req, res, next) {
    var ipInfo = getIP(req);
    console.log(ipInfo);
    // { clientIp: '127.0.0.1', clientIpRoutable: false }
    next();
});

它将尽最大努力获取用户的IP地址或返回127.0.0.1以表明它无法确定用户的IP地址。请查看 README 文件以获取高级选项。

答案 4 :(得分:19)

您可以使用request-ip来检索用户的IP地址。它处理了相当多的不同边缘情况,其中一些在其他答案中提到。

披露:我创建了这个模块

安装:

npm install request-ip

在您的应用中:

var requestIp = require('request-ip');

// inside middleware handler
var ipMiddleware = function(req, res, next) {
    var clientIp = requestIp.getClientIp(req); // on localhost > 127.0.0.1
    next();
};

希望这有帮助

答案 5 :(得分:12)

request.headers['x-forwarded-for'] || request.connection.remoteAddress

如果x-forwarded-for标头在那里,那么使用它,否则使用.remoteAddress属性。

x-forwarded-for标头会添加到通过为 HTTP HTTPS 设置的负载均衡器(或其他类型的代理)的请求中(也可能)使用代理协议 TCP 级别进行平衡时,将此标头添加到请求中。这是因为request.connection.remoteAddress属性将包含负载均衡器的私有IP地址,而不是客户端的公共IP地址。通过使用 OR 语句,按上面的顺序,检查是否存在x-forwarded-for标头,如果存在则使用它,否则使用request.connection.remoteAddress

答案 6 :(得分:12)

以下功能涵盖所有案例都有帮助

var ip;
if (req.headers['x-forwarded-for']) {
    ip = req.headers['x-forwarded-for'].split(",")[0];
} else if (req.connection && req.connection.remoteAddress) {
    ip = req.connection.remoteAddress;
} else {
    ip = req.ip;
}console.log("client IP is *********************" + ip);

答案 7 :(得分:7)

有两种获取IP地址的方法:

  1. let ip = req.ip

  2. let ip = req.connection.remoteAddress;

  3. 但是上述方法存在问题。

    如果您在Nginx或任何代理服务器后面运行应用程序,则每个IP地址都为127.0.0.1

    因此,获取用户IP地址的最佳解决方案是: -

    let ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
    

答案 8 :(得分:7)

function getCallerIP(request) {
    var ip = request.headers['x-forwarded-for'] ||
        request.connection.remoteAddress ||
        request.socket.remoteAddress ||
        request.connection.socket.remoteAddress;
    ip = ip.split(',')[0];
    ip = ip.split(':').slice(-1); //in case the ip returned in a format: "::ffff:146.xxx.xxx.xxx"
    return ip;
}

答案 9 :(得分:6)

如果您使用快速版本3.x或更高版本,则可以使用信任代理设置(http://expressjs.com/api.html#trust.proxy.options.table),它将遍历x-forwarded-for标头中的地址链并放置您未在req对象的ip属性中配置为可信代理的链中的最新IP。

答案 10 :(得分:3)

如果您获得多个IP,这对我有用:

var ipaddress = (req.headers['x-forwarded-for'] || 
req.connection.remoteAddress || 
req.socket.remoteAddress || 
req.connection.socket.remoteAddress).split(",")[0];

答案 11 :(得分:3)

在nodejs中简单获取远程ip:

var ip = req.header('x-forwarded-for') || req.connection.remoteAddress;

答案 12 :(得分:2)

我意识到这已经死了,但这是我写的一个现代的ES6版本,它遵循基于airbnb的eslint标准。

const getIpAddressFromRequest = (request) => {
  let ipAddr = request.connection.remoteAddress;

  if (request.headers && request.headers['x-forwarded-for']) {
    [ipAddr] = request.headers['x-forwarded-for'].split(',');
  }

  return ipAddr;
};

X-Forwarded-For标头可能包含逗号分隔的代理IP列表。订单是client,proxy1,proxy2,...,proxyN。在现实世界中,人们实现了可以在此标头中提供所需内容的代理。如果您位于负载均衡器之类,则至少可以相信列表中的第一个IP至少是某些请求通过的代理。

答案 13 :(得分:2)

我在nginx和

后面使用Express
req.headers.origin

对我有用吗

答案 14 :(得分:2)

我尝试了所有这些都没有用,

console.log(clientIp);
console.log(req.ip);

console.log(req.headers['x-forwarded-for']);
console.log(req.connection.remoteAddress);
console.log(req.socket.remoteAddress);
console.log(req.connection.socket.remoteAddress.split(",")[0]);

在为我Nginx的代理后面运行Express应用时,必须将应用变量信任代理设置为true。 Express提供了其他一些信任代理值,您可以在其文档中进行查看,但以下步骤对我有用。

  1. app.set('trust proxy',true)在您的Express应用中。

app.set('trust proxy', true);

  1. 在Nginx中添加proxy_set_header X-Forwarded-For $ remote_addr 服务器块的配置。
  location /  {
                proxy_pass    http://localhost:3001;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;  # this line
                proxy_cache_bypass $http_upgrade; 
        }
  1. 您现在可以从 req.header('x-forwarded-for')或req.connection.remoteAddress; ipfilter的完整代码
module.exports =  function(req, res, next) {
    let enable = true; // true/false
    let blacklist = ['x.x.x.x'];
    let whitelist = ['x.x.x.x'];
    let clientIp = req.header('x-forwarded-for') || req.connection.remoteAddress;
    if (!clientIp) {
        return res.json('Error');
    }
    if (enable
        && paths.some((path) => (path === req.originalUrl))) {

        let blacklist = blacklist || [];
        if (blacklist.some((ip) => clientIp.match(ip) !== null)) {
            return res.json({ status: 401, error: 'Your IP is black-listed !'});
        }
        let whitelist = whitelist || [];
        if (whitelist.length === 0 || whitelist.some((ip) => clientIp.match(ip) !== null)) {
            next();
            return;
        } else {
            return res.json({ status: 401, error: 'Your IP is not listed !'});
        }
    }
    next();
};

答案 15 :(得分:2)

req.connection 已被弃用 since node@12.12.0。使用 req.connection.remoteAddress 获取客户端 IP 可能仍然有效,但不鼓励使用。

幸运的是,req.socket.remoteAddress 从 node@0.5.10 开始就已经存在并且是一个完美的替代品:

<块引用>

远程 IP 地址的字符串表示形式。例如,'74.125.127.100''2001:4860:a005::68'。如果套接字被破坏(例如,如果客户端断开连接),则值可能为 undefined

答案 16 :(得分:1)

如果您使用的是Graphql-Yoga,则可以使用以下功能:

const getRequestIpAddress = (request) => {
    const requestIpAddress = request.request.headers['X-Forwarded-For'] || request.request.connection.remoteAddress
    if (!requestIpAddress) return null

    const ipv4 = new RegExp("(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")

    const [ipAddress] = requestIpAddress.match(ipv4)

    return ipAddress
}

答案 17 :(得分:1)

如果您使用 express.js,

app.post('/get/ip/address', function (req, res) {
      res.send(req.ip);
})

答案 18 :(得分:0)

在nginx后面的节点10.14中,您可以通过nginx标头中的请求来获取ip,如下所示:

proxy_set_header X-Real-IP $remote_addr;

然后在您的app.js中:

app.set('trust proxy', true);

之后,无论您希望它出现在什么地方:

var userIp = req.header('X-Real-IP') || req.connection.remoteAddress;

答案 19 :(得分:0)

警告:

不要盲目地将其用于重要的速率限制:

var x = 0.6;

if (x < 0.5) {
  console.log("less");
}
else if (x > 0.5) {
  console.log("more");
}
else {
  console.log("its the dflt");
}

console.log(x);

很容易欺骗:

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

在这种情况下,该用户的真实IP地址为:

curl --header "X-Forwarded-For: 1.2.3.4" "https://example.com"

我很惊讶没有其他答案提到这一点。

答案 20 :(得分:0)

    const express = require('express')
    const app = express()
    const port = 3000

    app.get('/', (req, res) => {
    var ip = req.ip
    console.log(ip);
    res.send('Hello World!')
    })

   // Run as nodejs ip.js
    app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
    })

答案 21 :(得分:0)

var ipaddress = (req.headers['x-forwarded-for'] || 
req.connection.remoteAddress || 
req.socket.remoteAddress || 
req.connection.socket.remoteAddress).split(",")[0];

答案 22 :(得分:-3)

use(function(req, res, next) { var ipInfo = getIP(req); console.log(ipInfo); // { clientIp: '127.0.0.1', clientIpRoutable: false } next(); }) ;

答案 23 :(得分:-6)

有同样的问题...我也是javascript的新手,但我用req.connection.remoteAddress解决了这个问题;给了我IP地址(但是用ipv6格式:: ffff.192.168.0.101)然后用 .slice 删除了7位数字。

var ip = req.connection.remoteAddress;

if (ip.length < 15) 
{   
   ip = ip;
}
else
{
   var nyIP = ip.slice(7);
   ip = nyIP;
}