如何在Node中确定用户的IP地址

518

我该如何在控制器中确定给定请求的IP地址?例如(在express中):

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

49
如果你正在使用Express,可以使用req.ip - FrickeFresh
尝试一下这个:https://github.com/indutny/node-ip - Stephen Last
62
对于那些像我一样从localhost工作的人,下面所有答案的结果几乎都会出现::1。这让我困惑了一段时间。后来发现::1是真正的IP地址,是本地主机的IPV6表示法。希望这能帮助到某些人。 - Pramesh Bajracharya
Cloudflare 获取客户端 IP req.headers['cf-connecting-ip'] - Muhammad Shahzad
33个回答

2

对我来说,使用 Kubernetes Ingress (NGINX):

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

在Node.js中运行得非常好


1
这个方法有效。获取代理后面的实际IP地址。 - Vijay Vavdiya
很高兴听到这个消息.. :) - Nikos445

2

我使用这个格式来表示IPv4地址

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

2

您可以使用Express这样获取用户IP地址:

req.ip

例如,在此示例中,我们获取用户的IP地址,并使用req.ip将其发送回用户。

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

req.ip may also include an IPv4 subnet prefix ::ffff: - as explained in this answer. easy to filter out --> req.ip.toString().replace('::ffff:', ''); - neonwatty

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
}


1
我正在使用Nginx后面的Express。
req.headers.origin

对我很有用


这个答案似乎不太准确。req.headers.orgin 返回的是客户端浏览器应用程序指向的 IP 地址,而不是客户端本身的 IP。 - zipzit

1
如果使用 Express
const ip = req.ip?.replace(/^.*:/, '') //->192.168.0.101

或者

const ip_raw = req.headers['x-forwarded-for'] ||
     req.socket.remoteAddress ||
     null; //->:ffff:192.168.0.101
const ip = ip_raw?.replace(/^.*:/, '')//->192.168.0.101

note: req.ip?.replace(/^.*:/, '')
            ^             ^
      null secure      regular expressin
    (if ip=!null continue to apply a regular expression)

1
嗯,最后我的解决方案是“这取决于!” 例如,如果你使用NGINX作为Web服务器,请查看你的配置文件,比如:
server {
    listen 443 ssl;
    server_name <your-domain>;

    ssl_certificate /etc/letsencrypt/live/<your-domain>/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/<your-domain>/privkey.pem; # managed by Certbot
    
    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr; # THIS LINE !!!!
    }
}

所以重点是 $remote_addr => x-real-ip 所以在Node.js中只需输入 req.headers["x-real-ip"]
就这样!

0
在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 */})

1
我认为你误解了问题。OP并不想要服务器IP地址,而是连接客户端的IP地址。 - nuts
好的,那就是这样!抱歉,我以为他想要服务器IP... - Shaurya Chhabra
你也可以使用浏览器的默认fetch来实现这个功能...所以,我的答案仍然适用! - Shaurya Chhabra

0
在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的响应。

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}`)
    })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接