Koa IP Filter Middleware
raw JSON →The `koa-ip` package provides a robust IP filtering middleware specifically designed for Koa applications. It allows developers to manage network access by configuring either a `whitelist` to permit specific IP addresses or a `blacklist` to deny them. The package accommodates both literal IP strings and regular expressions for defining patterns, enabling flexible control over single IPs, IP ranges, or subnets. Currently stable at version 2.1.4, `koa-ip` exhibits a stable release cadence, typical for well-defined utility middleware, suggesting ongoing maintenance rather than rapid feature development. Its key differentiators include a minimalist API, seamless integration into the Koa middleware chain, and built-in TypeScript definitions, making it easy to adopt in modern Koa projects. By default, it returns a 403 Forbidden status for blacklisted IPs, a behavior that can be customized with an asynchronous handler function, offering fine-grained control over denied requests.
Common errors
error TypeError: app.use is not a function ↓
const Koa = require('koa'); (or import Koa from 'koa';) and const app = new Koa(); at the start of your application file. error No IP filtering is occurring / Requests are not being blocked ↓
koa-ip is app.use()d early in your middleware stack. Double-check your whitelist and blacklist patterns. If behind a proxy, ensure app.proxy = true; is configured. error TypeScript Error: Module '"koa-ip"' has no default export. ↓
import ip = require('koa-ip'); or enable "esModuleInterop": true and "allowSyntheticDefaultImports": true in your tsconfig.json. Warnings
gotcha The order of middleware in Koa is crucial. `koa-ip` should be placed early in the middleware chain to ensure IP filtering occurs before other request handlers or route-matching logic. If placed too late, an unpermitted request might still be processed. ↓
gotcha By default, if an IP matches an entry in the `blacklist` and no custom `handler` function is provided, `koa-ip` will automatically set `ctx.status = 403`. Developers expecting a different default response or behavior must explicitly define a `handler`. ↓
gotcha When `app.proxy` is enabled in Koa (e.g., when behind a load balancer or reverse proxy), `ctx.request.ip` will use the `X-Forwarded-For` header. Ensure `app.proxy = true` is set if relying on forwarded headers, otherwise, `koa-ip` might filter based on the proxy's IP rather than the client's actual IP. ↓
gotcha IP patterns using regular expressions or wildcards (`*`) require careful construction. Incorrect patterns can inadvertently block legitimate users or fail to block malicious ones. For CIDR notation (e.g., '192.168.1.0/24'), ensure the library correctly interprets it or convert to appropriate regex if needed (though `koa-ip` supports CIDR directly). ↓
Install
npm install koa-ip yarn add koa-ip pnpm add koa-ip Imports
- ip
const ip = require('koa-ip'); - ip wrong
import { ip } from 'koa-ip';correctimport ip = require('koa-ip'); - ip wrong
import { ip } from 'koa-ip';correctimport ip from 'koa-ip';
Quickstart
import Koa from 'koa';
import ip from 'koa-ip';
const app = new Koa();
// Middleware to simulate ctx.request.ip for testing
// In a real application, ctx.request.ip is usually populated by Koa's proxy support or underlying Node.js
app.use(async (ctx, next) => {
if (ctx.url === '/test-blacklist') {
ctx.request.ip = '127.0.0.1'; // Simulate a blacklisted IP
} else if (ctx.url === '/test-whitelist') {
ctx.request.ip = '192.168.0.50'; // Simulate a whitelisted IP
} else {
ctx.request.ip = '203.0.113.1'; // Default IP for other requests
}
await next();
});
// Configure koa-ip with both whitelist and a blacklist with a custom handler
app.use(ip({
whitelist: ['192.168.0.*', /^10\.0\.\d{1,3}\.\d{1,3}$/], // Allow local subnet and 10.0.x.x
blacklist: ['127.0.0.1', '198.51.100.0/24'], // Deny localhost and a specific CIDR range
handler: async (ctx) => {
ctx.status = 403;
ctx.body = 'Access Denied: Your IP (' + ctx.request.ip + ') is not permitted.';
}
}));
// This middleware will only be reached if the IP is not blacklisted and matches whitelist (if whitelist is active)
app.use(async (ctx) => {
ctx.status = 200;
ctx.body = 'Welcome, your IP (' + ctx.request.ip + ') is allowed!';
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log('Try visiting these URLs:');
console.log(`- http://localhost:${PORT}/test-whitelist (should show welcome)`);
console.log(`- http://localhost:${PORT}/test-blacklist (should show access denied)`);
console.log(`- http://localhost:${PORT}/ (should show welcome if default IP is not blacklisted)`);
});