如何确定控制器中给定请求的IP地址?例如(快递):
app.post('/get/ip/address', function (req, res) {
// need access to IP address here
})
localhost
像我一样工作的人,下面所有答案的结果(几乎所有答案都可以)可能会来::1
。这让我有些困惑。后来发现这::1
是真实的IP地址,是IPV6
本地主机的表示法。 Hope this helps someone
如何确定控制器中给定请求的IP地址?例如(快递):
app.post('/get/ip/address', function (req, res) {
// need access to IP address here
})
localhost
像我一样工作的人,下面所有答案的结果(几乎所有答案都可以)可能会来::1
。这让我有些困惑。后来发现这::1
是真实的IP地址,是IPV6
本地主机的表示法。 Hope this helps someone
Answers:
您的request
对象中有一个称为的属性connection
,它是一个net.Socket
对象。net.Socket对象具有一个property remoteAddress
,因此您应该能够通过以下调用获取IP:
request.connection.remoteAddress
编辑
正如@juand在评论中指出的那样,如果服务器位于代理之后,则获取远程IP的正确方法是 request.headers['x-forwarded-for']
request.headers['x-forwarded-for']
var ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
(req.connection.socket ? req.connection.socket.remoteAddress : null);
请注意,有时您可以在中获得多个IP地址req.headers['x-forwarded-for']
。同样,x-forwarded-for
将不会始终设置可能引发错误的标头。
该字段的一般格式为:
x-for-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.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress
req.connection.socket
。我不知道为什么/在什么情况下会导致这种情况,但是最好检查是否req.connection.socket
存在这种情况,以免在这种情况下服务器崩溃。
您可以保持DRY状态,仅使用同时支持IPv4和IPv6的节点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地址。查看自述文件中的高级选项。
:ffff:(not my IP address)
从Heroku进行测试时,它为我返回了一些奇怪的信息。@ edmar-miyake的答案对我来说是正确的。
clientIp: '::1'
为我返回。它似乎不起作用。
您可以使用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();
};
希望这可以帮助
null
给我回来。
request.headers['x-forwarded-for']
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
。
以下功能涵盖了所有情况,将有所帮助
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);
,
对我而言介于两者之间。
有两种获取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;
如果您使用的是Express 3.x或更高版本,则可以使用信任代理设置(http://expressjs.com/api.html#trust.proxy.options.table),它将遍历地址链。 x-forwarded-for标头,然后将尚未配置为受信任代理的链中的最新ip放入req对象的ip属性中。
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;
}
不要盲目地将其用于重要的速率限制:
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];
我很惊讶没有其他答案提到这一点。
pop()
从阵列,这是比在索引1,其可以得到元件更一般的荷兰国际集团上当通过curl --header "X-Forwarded-For: 1.2.3.4, 5.6.7.8" "https://example.com"
。
如果您有多个IP,这对我有用:
var ipaddress = (req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress).split(",")[0];
我意识到这已经死了,但这是我写的一个现代的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至少是某些请求通过的代理。
如果您使用的是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
}
有同样的问题...我也是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;
}
ip= (ip.length<15?ip:(ip.substr(0,7)==='::ffff:'?ip.substr(7):undefined))
将替换上述代码中的if ...
function getClientIp4(req){ var ip=typeof req==='string'?req:getClientIp(req); return (ip.length<15?ip:(ip.substr(0,7)==='::ffff:'?ip.substr(7):undefined)); }
接受先前获取的ip或请求对象作为输入并给出ip或未定义的结果
req.ip
源- expressjs.com/en/api.html#req.ip