如何从控制器中确定给定请求的IP地址?例如(明确表示):
app.post('/get/ip/address', function (req, res) {
// need access to IP address here
})
答案 0 :(得分:384)
在request
对象中有一个名为connection
的属性,它是一个net.Socket
对象。 net.Socket对象具有属性remoteAddress
,因此您应该能够通过此调用获取IP:
request.connection.remoteAddress
的文档
修改强>
正如@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地址。在此示例中,请求通过proxy1
,proxy2
,然后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)
答案 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地址的方法:
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;
答案 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和
后面使用Expressreq.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提供了其他一些信任代理值,您可以在其文档中进行查看,但以下步骤对我有用。
app.set('trust proxy', true);
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; }
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;
}