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

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

当前回答

var ip = req.headers['x-forwarded-for'] ||
     req.socket.remoteAddress ||
     null;

请注意,有时您可以在req.headers['x-forwarded-for']中获得多个IP地址。此外,并不总是设置x-forward -for报头,这可能会抛出错误。

该字段的一般格式为:

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

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

这是Arnav Gupta提出的解决方案,Martin在下面的评论中为未设置x-forward -for的情况提出了修复建议:

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

使用现代JS的建议:

仅在设置时处理x-forward -for,如果设置了,则取第一个地址 其他参数使用可选链接(?.)

const parseIp = (req) =>
    req.headers['x-forwarded-for']?.split(',').shift()
    || req.socket?.remoteAddress

console.log(parseIp(req))
// => 127.0.0.1

其他回答

在Typescript中使用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的响应。

如果你使用express.js,

app.post('/get/ip/address', function (req, res) {
      res.send(req.ip);
})
var ip = req.headers['x-forwarded-for'] ||
     req.socket.remoteAddress ||
     null;

请注意,有时您可以在req.headers['x-forwarded-for']中获得多个IP地址。此外,并不总是设置x-forward -for报头,这可能会抛出错误。

该字段的一般格式为:

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

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

这是Arnav Gupta提出的解决方案,Martin在下面的评论中为未设置x-forward -for的情况提出了修复建议:

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

使用现代JS的建议:

仅在设置时处理x-forward -for,如果设置了,则取第一个地址 其他参数使用可选链接(?.)

const parseIp = (req) =>
    req.headers['x-forwarded-for']?.split(',').shift()
    || req.socket?.remoteAddress

console.log(parseIp(req))
// => 127.0.0.1

在你的请求对象中有一个属性叫socket,它是一个网络。套接字对象。净。套接字对象有一个属性remoteAddress,因此你应该能够通过这个调用得到IP:

request.socket.remoteAddress

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

EDIT

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

编辑2

在Node.js中使用express时:

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

你可以保持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文件中的高级选项。