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

如何从控制器内确定给定请求的IP地址?例如(在快递中):

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

在你的request对象中有一个名为socket的属性,它是一个net.Socket对象。net.Socket对象有一个属性remoteAddress,因此你应该能够通过这个调用获得IP:

request.socket.remoteAddress

(如果你的节点版本低于13,使用已弃用的request.connection.remoteAddress)

编辑

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

编辑2

在Node.js中使用express时:

如果你设置app.set('trust proxy', true)req.ip将返回真实IP地址,即使在代理之后。查看文档了解更多信息

var 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地址。在本例中,请求通过proxy1proxy2proxy3传递。proxy3显示为请求的远程地址。

这是Arnav古普塔建议的解决方案,并在下面的评论中为未设置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

你可以保留,只使用同时支持IPv4IPv6< a href = " https://github.com/un33k/node-ipware " > 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地址。查看一下< a href = " https://github.com/un33k/node-ipware/blob/master/README.md " > README < / >文件中的高级选项。

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

你可以使用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();
};

希望这能有所帮助

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

如果有x-forwarded-for标头,则使用它,否则使用.remoteAddress属性。

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

也有同样的问题…im也是新的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;
}

以下函数涵盖了所有的情况,将会有所帮助

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);

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;
}

如果使用express…

req.ip

我在查这个,然后我想,等等,我用的是快递。咄。

如果你有多个ip,这对我来说是可行的:

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

在nodejs中简单获取远程ip:

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

获取ip地址有两种方式:

  1. let ip = req.ip

  2. let ip = req.connection.remoteAddress;

但上述方法存在一个问题。

如果你在Nginx或任何代理后运行你的应用程序,每个IP地址都将是127.0.0.1

因此,获取user的ip地址的最佳方案是:-

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

我知道这个问题已经被回答了,但下面是我写的一个现代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至少是某个请求通过的代理。

在节点10.14中,在nginx后面,你可以通过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;

警告:

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

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];

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

如果你正在使用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
}

我在nginx后面使用express和

req.headers.origin

对我有用吗

我试过了,但都没用,

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)

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. 您现在可以读取客户端的IP地址 req.header('x-forwarded-for')或req.connection.remoteAddress;ipfilter
  2. 的完整代码
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();
};
    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}`)
})

req.connection已弃用自从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

如果你使用express.js,

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

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

这里有很多很棒的观点,但没有一个是全面的,所以这里是我最终使用的:

function getIP(req) {
// req.connection is deprecated
const conRemoteAddress = req.connection?.remoteAddress
// req.socket is said to replace req.connection
const sockRemoteAddress = req.socket?.remoteAddress
// some platforms use x-real-ip
const xRealIP = req.headers['x-real-ip']
// most proxies use x-forwarded-for
const xForwardedForIP = (() => {
const xForwardedFor = req.headers['x-forwarded-for']
if (xForwardedFor) {
// The x-forwarded-for header can contain a comma-separated list of
// IP's. Further, some are comma separated with spaces, so whitespace is trimmed.
const ips = xForwardedFor.split(',').map(ip => ip.trim())
return ips[0]
}
})()
// prefer x-forwarded-for and fallback to the others
return xForwardedForIP || xRealIP || sockRemoteAddress || conRemoteAddress
}

我使用这个ipv4格式

req.connection.remoteAddress.split(':').slice(-1)[0]

我们可以在node js中检查这段代码

const os       = require('os');
const interfaces = os.networkInterfaces();


let addresses = [];


for (var k in interfaces) {


for (var k2 in interfaces[k]) {


const address = interfaces[k][k2];


if ( (address.family === 'IPv4' || address.family === 'IPv6')  &&
!address.internal) {


addresses.push(address.address);


}
}
}
console.log(addresses);

在shell中,你只需要curl https://api.ipify.org

所以,让我们观察一下,把它移植到node.js!

curl是一个从网站获取数据的应用程序,我们通过网站"https://api.ipify.org"作为论证。我们可以使用node-fetch来替换curl!

我们从网站上获得的数据是我们的IP地址,这是一种获取你的IP地址的东西。

总结一下:

const fetch = require('node-fetch');


fetch('https://api.ipify.org')
.then(response => {/* whatever */})
.catch(err => {/* whatever */})

首先,在你的项目中安装request-ip

import requestIp from 'request-ip';
const clientIp = requestIp.getClientIp(req);
console.log(clientIp)

如果你在localhost上工作,结果可能是::1,因为::1是真实的IP地址,是localhost的IPV6符号。

你可以像这样快速获取用户Ip

req.ip

在这个例子中,我们获取了用户的Ip,然后用req.ip把它发回给用户

app.get('/', (req, res)=> {
res.send({ ip : req.ip})
    

})

打印稿中使用ValidatorJS。下面是NodeJS中间件:

// Extract Client IP Address
app.use((req, res, next) => {
let ipAddress = (req.headers['x-forwarded-for'] as string || '').split(',')[0]
if (!validator.isIP(ipAddress))
ipAddress = req.socket.remoteAddress?.toString().split(':').pop() || ''
if (!validator.isIP(ipAddress))
return res.status(400).json({errorMessage: 'Bad Request'})


req.headers['x-forwarded-for'] = ipAddress
next()
})

在这里,我假设所有请求都应该有一个有效的IP地址,因此如果没有找到有效的IP地址,则返回一个代码为400的响应。

对于我使用kubernetes ingress (NGINX):

req.headers['x-original-forwarded-for']

在Node.js中非常有效