Laravel限流中间件精准放行特定IP需确保白名单中间件在throttle之前执行,通过配置TrustProxies获取真实IP,使用支持CIDR和IPv6的校验函数比对config('firewall.whitelist'),匹配则放行,否则返回429响应。

当Laravel的限流中间件(如throttle:60,1)把运维、测试或内网接口请求也拦住时,必须在不关闭限流的前提下精准放行特定IP或IP段——这要求白名单配置能绕过速率限制逻辑,且支持CIDR网段与IPv6。
确认限流中间件执行位置
打开app/Http/Kernel.php,找到$middlewareGroups['api']或$middlewareGroups['web']数组;限流中间件throttle:60,1必须放在白名单中间件之后,否则白名单逻辑根本不会被执行。
若当前结构是throttle:60,1 → IpWhitelist::class,请立即调换顺序:改成IpWhitelist::class → throttle:60,1。顺序错误会导致白名单失效,所有请求仍被限流。
创建IP白名单中间件
运行命令:php artisan make:middleware IpWhitelist。
编辑生成的app/Http/Middleware/IpWhitelist.php,在handle()方法中写入以下逻辑:
先从配置读取白名单:$whitelist = config('firewall.whitelist', []);;再获取真实IP:$ip = $request->ip();;最后用in_whitelist($ip, $whitelist)函数校验——这个函数需自行实现,不能只用in_array(),因为要支持CIDR和IPv6。
【务必检查$ip是否为null或127.0.0.1】——若返回空或本地地址,说明TrustProxies未正确配置,白名单判断将永远失败。
支持CIDR与IPv6的白名单校验函数
在app/Helpers/NetworkHelper.php中新增函数:
第一步:用filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)确保输入是合法IP格式;
第二步:遍历白名单数组,对每个条目做分支判断——若条目含/(如192.168.1.0/24),调用ip_in_cidr($ip, $entry);若为纯IPv6(含::),用inet_pton()转二进制后比对前缀长度;若为单IP(如203.0.113.5),直接字符串比较;
第三步:任一匹配即返回true,全部不匹配才返回false。该函数必须能区分::1与0:0:0:0:0:0:0:1——它们是同一地址但字符串不同,需先标准化再比对。
配置可信代理与真实IP解析
打开app/Http/Middleware/TrustProxies.php,设置protected $proxies为实际负载均衡器或反向代理IP列表,例如:['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '203.0.113.10'];
确认protected $headers包含Illuminate\Http\Request::HEADER_X_FORWARDED_FOR(默认已启用);
若使用Cloudflare,还需在$headers中追加'CF-Connecting-IP',并把Cloudflare官方IP段加入$proxies数组——否则$request->ip()永远拿不到真实客户端IP。
注册白名单中间件并启用配置
在config/firewall.php中定义白名单配置项:
return ['whitelist' => ['192.168.1.100', '2001:db8::1', '10.0.0.0/8']];
在app/Http/Kernel.php的$middleware数组顶部添加:App\Http\Middleware\IpWhitelist::class;
在handle()中,若校验通过,直接return $next($request);若不通过,return response('', 429)->header('X-RateLimit-Remaining', 0)——注意不要用abort(429),它会触发异常渲染流程,增加响应延迟。











