Mateen Kiani
Published on Sun Jul 06 2025·5 min read
Node.js applications often need to know where a request comes from. You might log visitor locations, block suspicious traffic, or customize content by region. But there’s one piece that trips up many developers: reliably getting the client’s real IP address when proxies or load balancers sit in front of your server. How can you capture the true origin instead of just grabbing an internal address?
The answer lies in understanding the key headers, the built-in properties of Node’s HTTP objects, and the right configuration for popular frameworks like Express. Once you know these tricks, you’ll avoid analytics gaps, tighten security, and ensure logs show accurate client IPs. Let’s dive into how to get the IP address in Node.js—and why each step matters.
Every device on the internet carries an IP address. It can be IPv4 (like 192.168.0.1) or IPv6 (like fe80::1ff:fe23:4567:890a). Knowing which version you’re handling helps parse addresses correctly and avoid surprises when logging or validating.
Private vs. Public Addresses
Why this matters: if you log a private IP, you’re likely seeing a proxy or load balancer, not the client. Many Node.js servers report 127.0.0.1 or an internal range by default. To get the true client IP, you need to go beyond the raw socket data.
Tip: Always keep an eye on both IPv4 and IPv6 formats in your logs. Parsing one format only can break your analytics when a mobile user switches networks.
Node’s built-in http
module exposes connection properties where IPs live. Here’s a basic example:
const http = require('http');http.createServer((req, res) => {const remote = req.socket.remoteAddress;console.log('Client IP:', remote);res.end('Your IP is ' + remote);}).listen(3000, () => console.log('Listening on 3000'));
In older Node versions you might see req.connection.remoteAddress
, but that’s an alias for req.socket.remoteAddress
now. This value works fine when there’s no proxy in between. But as soon as you add a load balancer or reverse proxy, that address changes to the proxy’s IP.
Tip: Always test your raw HTTP code locally before deploying behind proxies. Tools like Postman or
curl
help you confirm thatremoteAddress
returns what you expect.
Express simplifies web server work, including IP handling. Use req.ip
to get the client’s address:
const express = require('express');const app = express();app.set('trust proxy', true); // enable if behind proxyapp.get('/', (req, res) => {console.log('Client IP:', req.ip);res.send(`Hello from ${req.ip}`);});app.listen(3000);
By default, req.ip
reads the remote socket address. If you set trust proxy
, Express’ll look at the X-Forwarded-For
header instead—crucial when a reverse proxy passes the real client IP.
Express also exposes req.ips
when multiple proxies add their own IPs in the forwarding chain. The first IP in that array is the original client, and the rest are proxies.
Most production setups place Nginx, HAProxy, or a cloud load balancer in front of your Node app. Those proxies forward the client IP in special headers:
You can parse them yourself in plain HTTP servers:
const http = require('http');http.createServer((req, res) => {const header = req.headers['x-forwarded-for'];const ip = header ? header.split(',')[0].trim() : req.socket.remoteAddress;console.log('Real IP:', ip);res.end(ip);}).listen(3000);
Here’s what happens:
Tip: Ensure your proxy only adds or overwrites
X-Forwarded-For
. Malicious clients can fake it if you accept user-supplied headers.
Sometimes you need the public IP of your server rather than a client’s IP. Or you want a quick validation that your code sees the expected external address. External APIs like ipify.org come in handy. You can fetch your public IP like this:
const https = require('https');https.get('https://api.ipify.org?format=json', (res) => {let data = '';res.on('data', chunk => data += chunk);res.on('end', () => console.log('Public IP:', JSON.parse(data).ip));});
For more advanced HTTP handling—timeouts, retries, or proxies—check out making HTTP requests in Node.js.
If you need the IPs of your development machine or server network interfaces, use Node’s os
module:
const os = require('os');const nets = os.networkInterfaces();const results = {};for (const name of Object.keys(nets)) {for (const net of nets[name]) {if (!net.internal) {results[name] = results[name] || [];results[name].push(net.address);}}}console.log('Local IPs:', results);
This snippet iterates all network interfaces, filters out internal (loopback) addresses, and groups the public ones by interface name. Use this when you spin up development servers or Docker containers and need to know which IP to bind.
Pro Tip: You can pipe this output to a JSON file for later inspection. Learn how to save JSON to file in Node.js.
Grabbing the correct IP address in Node.js goes beyond one line of code. You need to handle raw sockets, framework helpers like req.ip
, and headers injected by proxies or load balancers. Understanding IPv4 vs. IPv6, the meaning of private versus public addresses, and how external services operate puts you in full control. Armed with these techniques, you’ll keep logs accurate, improve security checks, and build features—like geo-targeting—with confidence. Next time you see 127.0.0.1 in your logs, you’ll know exactly where to look and how to surface the real client IP. Happy coding!