UNPKG

get-client-ip

Version:

📍 A Lightweight Utility for Extracting the Real Client IP Address from Incoming HTTP Requests

148 lines (104 loc) 5.87 kB
<div align="center"> <img src="https://github.com/WolfieLeader/npm/blob/main/assets/get-client-ip-banner.svg" align="center" alt="banner" /> <h1 align="center">get-client-ip</h1> <p align="center"> Extract the real client IP from HTTP requests.<br/> Works standalone or as Express/NestJS middleware. </p> <a href="https://opensource.org/licenses/MIT" rel="nofollow"><img src="https://img.shields.io/github/license/WolfieLeader/npm?color=DC343B" alt="License"></a> <a href="https://www.npmjs.com/package/get-client-ip" rel="nofollow"><img src="https://img.shields.io/npm/v/get-client-ip?color=0078D4" alt="npm version"></a> <a href="https://www.npmjs.com/package/get-client-ip" rel="nofollow"><img src="https://img.shields.io/npm/dt/get-client-ip.svg?color=03C03C" alt="npm downloads"></a> <a href="https://github.com/WolfieLeader/npm" rel="nofollow"><img src="https://img.shields.io/github/stars/WolfieLeader/npm" alt="stars"></a> </div> ## Highlights - **Checks 14 sources** (headers + socket) in priority order - **Handles** comma-separated, array, and RFC 7239 `Forwarded` formats - **Framework compatibility** — supports Express v5/v4 and NestJS (Express adapter) - **Flexible usage** — works standalone or as middleware, and auto-populates typed `req.clientIp` and `req.clientIps` - **Zero config** — validates IPs using Node.js `net.isIP()` ## Installation 📦 Requires Node.js >= 18. ```bash npm install get-client-ip # or pnpm add get-client-ip ``` ## Quick Start 🚀 ```typescript import express from "express"; import { getClientIp } from "get-client-ip"; const app = express(); // Middleware — auto-populates req.clientIp and req.clientIps app.use(getClientIp); app.get("/me", (req, res) => { res.json({ ip: req.clientIp, ips: req.clientIps }); }); // Or standalone — call directly in a specific route app.get("/ip", (req, res) => { const ip = getClientIp(req); res.json({ ip }); }); app.listen(3000); ``` ## API Reference 📖 ### `getClientIp(req, res?, next?): string | undefined` Extracts the client's IP address from an incoming request. Works both as a standalone function and as Express middleware. Returns `string | undefined`. **Side effects:** Sets `req.clientIp` and `req.clientIps` on the request object when a valid IP is found. Throws if `req` is `undefined`. ### TypeScript Augmentation The package augments the Express `Request` type automatically: ```typescript // These properties are available after calling getClientIp req.clientIp; // string | undefined — first valid IP req.clientIps; // [string, ...string[]] | undefined — all valid IPs (non-empty array) ``` No manual type declarations are needed. ## Header Priority 📋 Sources are checked in the following order. The first valid IP found is returned. | Priority | Source | Description | | -------- | -------------------------- | -------------------------------------- | | 1 | `req.ip` | Express `trust proxy` setting | | 2 | `Forwarded` | RFC 7239 (parsed for `for=` directive) | | 3 | `CF-Connecting-IP` | Cloudflare | | 4 | `True-Client-IP` | Akamai / Cloudflare Enterprise | | 5 | `Fastly-Client-IP` | Fastly CDN | | 6 | `X-Appengine-User-IP` | Google App Engine | | 7 | `CF-Pseudo-IPv4` | Cloudflare pseudo-IPv4 | | 8 | `X-Client-IP` | General proxy header | | 9 | `X-Forwarded-For` | De facto standard proxy header | | 10 | `Forwarded-For` | Variant of X-Forwarded-For | | 11 | `X-Forwarded` | Microsoft variant | | 12 | `X-Real-IP` | Nginx proxy header | | 13 | `X-Cluster-Client-IP` | Rackspace / Riverbed | | 14 | `req.socket.remoteAddress` | Direct connection fallback | ## NestJS 🧩 ```typescript import { Controller, Get, Req } from "@nestjs/common"; import type { Request } from "express"; import { getClientIp } from "get-client-ip"; @Controller() export class AppController { @Get("ip") getIp(@Req() req: Request) { const ip = getClientIp(req); return { ip }; } } ``` ## Security 🛡️ > **Header trust warning:** When `req.ip` is not populated, forwarding headers are used only when `req.socket.remoteAddress` appears to be from a local/private proxy range. Public socket peers skip header fallback to reduce spoofing risk. **In production behind a reverse proxy:** 1. Configure Express's [`trust proxy`](https://expressjs.com/en/guide/behind-proxies.html) setting so that `req.ip` is correctly populated 2. This ensures the function returns `req.ip` first and avoids fallback ambiguity 3. Without `trust proxy`, forwarding headers may still be ignored when the peer is public > **CGNAT addresses:** Addresses in the `100.64.0.0/10` range (RFC 6598) are treated as public, not trusted proxy addresses. Headers are not trusted when the socket peer is a CGNAT address. If your application is behind a load balancer (e.g., AWS ALB), configure Express's `trust proxy` setting so `req.ip` is populated correctly. ## Credits 🙏 Inspired by [Petar Bojinov's](https://github.com/pbojinov) work on client IP detection. ## Contributions 🤝 - Open an [issue](https://github.com/WolfieLeader/npm/issues) or feature request - Submit a PR to improve the package - Star the repo if you find it useful <div align="center"> <br/> Crafted carefully by [WolfieLeader](https://github.com/WolfieLeader) This project is licensed under the [MIT License](https://opensource.org/licenses/MIT). </div>