0
0
Expressframework~15 mins

req.ip and req.hostname in Express - Deep Dive

Choose your learning style9 modes available
Overview - req.ip and req.hostname
What is it?
In Express, req.ip and req.hostname are properties of the request object that help identify the client making the request and the host the request was sent to. req.ip gives the IP address of the client, while req.hostname provides the domain name or host header from the request. These properties help servers understand where requests come from and which host they target.
Why it matters
Knowing the client's IP address and the hostname requested is crucial for security, logging, and routing decisions. Without these, servers cannot track users, apply access controls, or serve content correctly for different domains. For example, without req.ip, blocking malicious users or rate limiting is impossible. Without req.hostname, serving multiple websites from one server would be confusing.
Where it fits
Before learning req.ip and req.hostname, you should understand basic Express routing and the request-response cycle. After this, you can explore middleware for security, logging, or multi-tenant hosting that uses these properties to make decisions.
Mental Model
Core Idea
req.ip tells you who is asking, and req.hostname tells you what they are asking for.
Think of it like...
Imagine a receptionist at a building: req.ip is like the visitor's car license plate showing where they came from, and req.hostname is like the name of the company or office they want to visit inside the building.
┌─────────────┐       ┌───────────────┐
│   Client    │──────▶│   Express     │
│ (IP address)│       │  Server       │
└─────────────┘       └───────────────┘
       │                      │
       │                      │
       │                      │
       ▼                      ▼
  req.ip (client IP)     req.hostname (requested host)
Build-Up - 6 Steps
1
FoundationUnderstanding req.ip basics
🤔
Concept: req.ip gives the IP address of the client making the request.
When a client (like a browser) sends a request to an Express server, Express reads the IP address from the network connection and stores it in req.ip. This IP can be IPv4 or IPv6. For example, if your browser connects from 192.168.1.5, req.ip will be '192.168.1.5'.
Result
You can access req.ip in your route handlers to know the client's IP address.
Understanding req.ip is key to identifying who is connecting, which is the foundation for security and analytics.
2
FoundationUnderstanding req.hostname basics
🤔
Concept: req.hostname gives the host name from the request's Host header.
HTTP requests include a Host header that tells the server which domain the client wants. Express reads this and stores it in req.hostname. For example, if the client requests 'https://example.com/page', req.hostname will be 'example.com'.
Result
You can use req.hostname to serve different content based on the requested domain.
Knowing req.hostname lets your server handle multiple domains or subdomains on the same Express app.
3
IntermediateHandling proxies with req.ip
🤔Before reading on: do you think req.ip always shows the user's real IP address or the proxy's IP? Commit to your answer.
Concept: When behind proxies, req.ip may show the proxy's IP unless configured to trust proxies.
If your Express app is behind a proxy (like a load balancer), req.ip by default shows the proxy's IP, not the client's real IP. To get the real client IP, you must set app.set('trust proxy', true). Then Express reads the X-Forwarded-For header to find the original IP.
Result
With trust proxy enabled, req.ip reflects the real client IP even behind proxies.
Knowing how proxies affect req.ip prevents mistaken IP logging and security errors.
4
IntermediateDifferences between req.hostname and req.headers.host
🤔Before reading on: do you think req.hostname and req.headers.host always contain the same value? Commit to your answer.
Concept: req.hostname is derived from req.headers.host but excludes the port number and is normalized.
req.headers.host contains the full Host header, including port (e.g., 'example.com:3000'). req.hostname strips the port and lowercases the domain (e.g., 'example.com'). This makes req.hostname easier to use for routing decisions.
Result
Using req.hostname avoids errors caused by port numbers or case differences.
Understanding this difference helps avoid bugs when matching hostnames in your code.
5
AdvancedSecurity considerations with req.ip and req.hostname
🤔Before reading on: do you think req.ip and req.hostname can be trusted blindly? Commit to your answer.
Concept: Clients can spoof headers; trusting req.ip and req.hostname without validation can cause security risks.
Attackers can fake Host headers or X-Forwarded-For headers to trick your server. Always validate req.hostname against allowed domains and configure trust proxy carefully. Never use req.ip alone for critical security decisions without additional checks.
Result
Proper validation prevents host header attacks and IP spoofing.
Knowing the limits of trust in these properties protects your app from common web attacks.
6
ExpertInternals of req.ip and req.hostname resolution
🤔Before reading on: do you think req.ip is read directly from the socket or from headers? Commit to your answer.
Concept: req.ip is read from the network socket or X-Forwarded-For header if trust proxy is enabled; req.hostname is parsed from the Host header.
Express reads the remote address from the underlying socket connection for req.ip. If trust proxy is enabled, it parses the X-Forwarded-For header to find the original client IP. For req.hostname, Express parses the Host header, removes the port if present, and lowercases the result. This parsing happens on every request.
Result
Understanding this helps debug issues with IP or hostname detection in complex network setups.
Knowing the exact source of these values clarifies why configuration matters and how Express handles requests internally.
Under the Hood
Express obtains req.ip from the network socket's remote address by default. When trust proxy is enabled, it reads the X-Forwarded-For header, which may contain multiple IPs, and selects the left-most as the client IP. For req.hostname, Express parses the Host header from the HTTP request, strips any port number, and lowercases the hostname for consistency.
Why designed this way?
This design balances simplicity and flexibility. Using the socket address works for direct connections, while trust proxy allows Express to work correctly behind proxies common in production. Parsing Host headers for req.hostname follows HTTP standards, enabling virtual hosting on one server.
┌───────────────┐
│ Client Request│
│  (HTTP)      │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Network Socket│
│ remoteAddress │
└──────┬────────┘
       │
       ▼
┌─────────────────────────────┐
│ Express req.ip determination │
│ if trust proxy:             │
│   parse X-Forwarded-For     │
│ else:                      │
│   use socket remoteAddress  │
└─────────────────────────────┘

┌─────────────────────────────┐
│ Express req.hostname parsing │
│ parse Host header           │
│ remove port number          │
│ lowercase hostname          │
└─────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does req.ip always show the real client IP even behind proxies? Commit to yes or no.
Common Belief:req.ip always contains the real client's IP address.
Tap to reveal reality
Reality:Without setting trust proxy, req.ip shows the proxy's IP, not the real client IP.
Why it matters:Misunderstanding this causes wrong IP logging and ineffective security controls.
Quick: Is req.hostname always safe to use without validation? Commit to yes or no.
Common Belief:req.hostname can be trusted as it comes from the client request.
Tap to reveal reality
Reality:req.hostname comes from the Host header, which clients can spoof.
Why it matters:Blindly trusting req.hostname can lead to host header attacks and security breaches.
Quick: Are req.hostname and req.headers.host exactly the same? Commit to yes or no.
Common Belief:req.hostname and req.headers.host always contain the same value.
Tap to reveal reality
Reality:req.hostname excludes the port and is lowercased, while req.headers.host includes the port and original casing.
Why it matters:Confusing these can cause bugs in domain matching and routing.
Quick: Does req.ip include IPv6 addresses? Commit to yes or no.
Common Belief:req.ip only contains IPv4 addresses.
Tap to reveal reality
Reality:req.ip can contain IPv6 addresses if the client uses IPv6.
Why it matters:Ignoring IPv6 can cause incomplete IP handling and errors in logging or security.
Expert Zone
1
When multiple proxies are involved, the X-Forwarded-For header can contain several IPs; Express trusts the left-most IP only if trust proxy is configured correctly.
2
req.hostname does not include the port number, so comparing it to req.headers.host without normalization can cause subtle bugs.
3
Setting trust proxy incorrectly (e.g., trusting all proxies blindly) can expose your app to IP spoofing attacks.
When NOT to use
Do not rely solely on req.ip for critical security decisions in untrusted networks; use additional authentication or network-level controls. For hostname-based routing, consider using dedicated reverse proxies or DNS configurations for stronger guarantees.
Production Patterns
In production, apps often enable trust proxy to get real client IPs behind load balancers. They validate req.hostname against a whitelist to prevent host header attacks. Logging middleware uses req.ip for analytics and rate limiting. Multi-tenant apps use req.hostname to serve different content per domain.
Connections
HTTP Headers
req.ip and req.hostname are derived from specific HTTP headers and network info.
Understanding HTTP headers like Host and X-Forwarded-For clarifies how Express extracts client and host info.
Network Proxies and Load Balancers
Proxies affect the values of req.ip and req.hostname by modifying headers and connection info.
Knowing how proxies work helps configure Express trust proxy settings correctly.
Security: Host Header Attacks
Improper use of req.hostname can lead to host header injection vulnerabilities.
Understanding req.hostname's origin helps prevent serious web security issues.
Common Pitfalls
#1Assuming req.ip always shows the real client IP without configuring trust proxy.
Wrong approach:app.get('/', (req, res) => { console.log(req.ip); res.send('Hello'); }); // trust proxy not set
Correct approach:app.set('trust proxy', true); app.get('/', (req, res) => { console.log(req.ip); res.send('Hello'); });
Root cause:Not understanding that behind proxies, req.ip defaults to the proxy's IP.
#2Using req.hostname without validating it against allowed domains.
Wrong approach:app.get('/', (req, res) => { if(req.hostname === 'mydomain.com') { res.send('Welcome'); } else { res.send('Blocked'); } }); // no validation
Correct approach:const allowedHosts = ['mydomain.com', 'www.mydomain.com']; app.get('/', (req, res) => { if(allowedHosts.includes(req.hostname)) { res.send('Welcome'); } else { res.status(400).send('Invalid Host'); } });
Root cause:Not realizing clients can spoof Host headers leading to security risks.
#3Comparing req.hostname directly to req.headers.host including port number.
Wrong approach:if(req.hostname === req.headers.host) { /* ... */ } // fails if port present
Correct approach:if(req.hostname === req.headers.host.split(':')[0]) { /* ... */ }
Root cause:Ignoring that req.headers.host may include port while req.hostname does not.
Key Takeaways
req.ip identifies the client's IP address, but behind proxies, you must enable trust proxy to get the real IP.
req.hostname extracts the domain name from the Host header, excluding the port and normalizing case.
Both req.ip and req.hostname come from client-supplied data and can be spoofed, so always validate them before use.
Understanding how proxies and headers affect these properties is essential for secure and correct Express apps.
Proper use of req.ip and req.hostname enables multi-domain hosting, security controls, and accurate logging.