如何无例外为所有路由(含未实现路由)注册中间件
全局IP白名单中间件实现(覆盖所有路由含404)
首先,核心思路是把IP校验中间件挂载在所有路由和404处理逻辑之前——Express的中间件是按注册顺序执行的,只要把校验逻辑放在最前面,所有进入服务器的请求(不管是已定义路由还是未匹配的404请求)都会先经过它。
第一步:编写IP白名单中间件
先写一个通用的中间件函数,校验请求IP是否在白名单内:
const allowedIPs = ['192.168.1.1', '10.0.0.5', '::1']; // 替换成你的白名单IP集合 const ipWhitelistMiddleware = (req, res, next) => { // 获取请求的真实IP:如果服务器在反向代理(Nginx/Cloudflare)后,需要先配置信任代理 const clientIP = req.ip || req.connection.remoteAddress || req.socket.remoteAddress; // 可选:统一IPv6本地IP格式,比如把::1转换成127.0.0.1 const normalizedIP = clientIP === '::1' ? '127.0.0.1' : clientIP; if (allowedIPs.includes(normalizedIP)) { next(); // IP合法,放行到后续逻辑 } else { res.status(403).send('Forbidden: Your IP is not in the whitelist'); // IP不合法,返回403 } };
第二步:全局挂载中间件(关键操作!)
一定要把这个中间件放在所有路由定义和404处理之前,这样所有请求都会先经过IP校验:
const express = require('express'); const app = express(); // 1. 优先挂载IP白名单中间件——这一步必须在业务路由之前! app.use(ipWhitelistMiddleware); // 2. 再定义你的业务路由 app.get('/r1', (req, res) => res.send('Welcome to Route 1')); app.get('/r2', (req, res) => res.send('Welcome to Route 2')); app.get('/r3', (req, res) => res.send('Welcome to Route 3')); // 3. 最后处理未匹配的路由(404) app.use((req, res) => { res.status(404).send('404: Page Not Found'); }); app.listen(3000, () => console.log('Server running on port 3000'));
为什么这样能解决问题?
- 中间件执行顺序:请求进来后先过IP校验,通过后才会尝试匹配业务路由;
- 未匹配路由的处理:当请求访问/4这类未定义路由时,业务路由匹配失败,会走到最后的404逻辑,但此时已经完成了IP校验,完全符合你的需求;
- 真正全局生效:不需要逐个路由手动绑定中间件,一次挂载就覆盖所有请求场景。
补充:反向代理场景下的真实IP获取
如果你的服务器部署在Nginx、Cloudflare这类反向代理后面,req.ip默认会拿到代理服务器的IP,而非客户端真实IP。这时候需要先配置Express信任代理:
// 在挂载中间件之前添加 app.set('trust proxy', true); // 信任所有代理,也可以指定具体的代理IP范围提升安全性
配置后req.ip就能正确获取到客户端的真实IP了。
内容的提问来源于stack exchange,提问作者27mdmo7sn
相关产品推荐
相关产品推荐

