我该如何在控制器中确定给定请求的IP地址?例如(在express中):
app.post('/get/ip/address', function (req, res) {
// need access to IP address here
})
在你的 request
对象中有一个叫做 socket
的属性,它是一个 net.Socket
对象。 net.Socket
对象有一个属性叫做remoteAddress
,因此您可以使用以下代码获取 IP 地址:
request.socket.remoteAddress
(如果您的Node版本低于13,请使用已弃用的现在request.connection.remoteAddress
)
编辑
如@juand在评论中指出,如果服务器在代理后面,则获取远程IP的正确方法是request.headers['x-forwarded-for']
编辑2
使用Node.js的express
时:
如果设置了app.set('trust proxy', true)
,则req.ip
将返回真实的IP地址,即使在代理后面。请查看文档以获取更多信息
request.headers['x-forwarded-for']
- FueledPublishingvar ip = req.headers['x-forwarded-for'] ||
req.socket.remoteAddress ||
null;
请注意,有时您可以在 req.headers['x-forwarded-for']
中获得多个 IP 地址。此外,x-forwarded-for
标头并不总是存在,这可能会导致错误。
字段的一般格式为:
x-forwarded-for: client, proxy1, proxy2, proxy3
其中值是一个由逗号和空格分隔的 IP 地址列表,最左边的是原始客户端,每个后继代理传递请求时添加其接收请求的 IP 地址。在这个例子中,请求通过 proxy1
、proxy2
,然后是 proxy3
。 proxy3
出现为请求的远程地址。
这是由 Arnav Gupta 建议的解决方案,并且 Martin 在下面的评论中提出了修复方法,用于处理未设置 x-forwarded-for
的情况:
var ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() ||
req.socket.remoteAddress
使用现代JS的建议:
x-forwarded-for
时处理,如果设置了,则取第一个地址const parseIp = (req) =>
req.headers['x-forwarded-for']?.split(',').shift()
|| req.socket?.remoteAddress
console.log(parseIp(req))
// => 127.0.0.1
req.connection.socket
。我不确定是什么原因或什么条件导致了这种情况,但最好检查一下req.connection.socket
是否存在,以避免在发生此情况时使服务器崩溃。 - Matt Browne您可以保持代码的干燥性并使用支持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文件以了解高级选项。:ffff:(不是我的IP地址)
。@edmar-miyake的答案对我有效。 - NillocclientIp: '::1'
。看起来它不起作用。 - JamEngulfernpm 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();
};
希望这能有所帮助。
null
. - S.M_Emamianrequest.headers['x-forwarded-for']
代替相同的事情 - Prathamesh Morerequest.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
。 我试过所有的方法,但都没有成功。
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应用程序时,需要将应用程序变量trust proxy设置为true。Express提供了一些其他的trust proxy值,您可以在其文档中查看,但是以下步骤适用于我。
app.set('trust proxy', true)
app.set('trust proxy', true);
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;
}
现在您可以从req.header('x-forwarded-for')或req.connection.remoteAddress读取客户端的IP地址;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();
};
以下函数涵盖了所有情况,将会有所帮助
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);
不要盲目地将此用于重要的速率限制:
let ip = request.headers['x-forwarded-for'].split(',')[0];
这很容易被欺骗:
curl --header "X-Forwarded-For: 1.2.3.4" "https://example.com"
在这种情况下,用户的真实IP地址将是:
let ip = request.headers['x-forwarded-for'].split(',')[1];
我很惊讶其他答案都没有提到这一点。
获取IP地址有两种方式:
let ip = req.ip
let ip = req.connection.remoteAddress;
但是以上方法存在一个问题。
如果您的应用程序在Nginx或任何代理后面运行,则每个IP地址都将是127.0.0.1
。
因此,获得用户IP地址的最佳解决方案是:
let ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
req.ip
。 - FrickeFreshlocalhost
工作的人,下面所有答案的结果几乎都会出现::1
。这让我困惑了一段时间。后来发现::1
是真正的IP地址,是本地主机的IPV6
表示法。希望这能帮助到某些人。 - Pramesh Bajracharyareq.headers['cf-connecting-ip']
- Muhammad Shahzad