Laravel在CDN环境下IP限流必须先配置TrustProxies中间件信任代理IP并正确处理CF-Connecting-IP等头,否则$request->ip()会返回CDN节点IP而非真实用户IP,导致限流失效;需验证$proxies匹配实际出口IP段、确保中间件执行顺序,并在RateLimiter中直接使用$request->ip()。

CDN环境下Laravel做IP限流时,直接用$request->ip()会把CDN节点IP当成用户IP,导致全站被限或完全失效——这不是代码写错了,而是代理链没对齐信任关系。
确认当前IP获取是否已被污染
在任意控制器中临时插入一行调试代码:dd($request->ip(), $_SERVER['REMOTE_ADDR'] ?? null, $request->header('X-Forwarded-For'));
如果输出显示127.0.0.1、10.0.0.x或172.16.x.x这类私有地址,说明你正被反向代理遮蔽;若X-Forwarded-For有值但$request->ip()没同步更新,证明TrustProxies中间件未生效。
这一步必须做,跳过会导致后续所有配置白忙。
配置可信代理链(关键一步)
打开app/Http/Middleware/TrustProxies.php文件。
将protected $proxies设为实际代理IP范围,不是写'*'就完事——生产环境滥用'*'等于开放伪造IP入口。【Cloudflare用户必须额外处理CF-Connecting-IP头】
方法一:已知CDN出口IP段(如AWS CloudFront官方公布的CIDR列表)
→ 把全部IP段填入数组,例如:protected $proxies = ['192.0.2.0/24', '203.0.113.0/24'];
方法二:使用Nginx或ELB等固定出口IP
→ 直接写死IP:protected $proxies = ['192.168.10.5', '192.168.10.6'];
方法三:内网+CDN混合架构(如Nginx → Cloudflare → 用户)
→ 需同时信任内网段和Cloudflare官方IP段,并在$headers中追加Request::HEADER_CF_CONNECTING_IP:
- 确认
protected $headers包含Request::HEADER_X_FORWARDED_FOR(默认已有) - 追加
Request::HEADER_CF_CONNECTING_IP到数组末尾 - 重载配置:
php artisan config:clear
验证真实IP是否可稳定获取
新建一个测试路由,返回$request->ip()结果:
Route::get('/debug-ip', function (Request $request) { return response()->json(['real_ip' => $request->ip()]); });
用curl模拟CDN头请求:curl -H "X-Forwarded-For: 203.0.113.45, 198.51.100.22" http://your.app/debug-ip
响应中real_ip必须是203.0.113.45——注意,不是逗号后面那一串。如果不是,检查TrustProxies中$proxies是否匹配你当前的代理出口IP,【不匹配则$request->ip()永远取不到首段真实IP】。
在限流中间件中安全使用IP
不要在RateLimiter::for()闭包里直接写$request->ip()——它可能还没经过TrustProxies中间件过滤。
确保你的限流中间件在TrustProxies之后执行。查看app/Http/Kernel.php中$middleware数组顺序,确认TrustProxies::class排在ThrottleRequests::class之前。
写限流规则时,显式调用$request->ip()即可,无需再解析X-Forwarded-For:->by($request->ip())
这一步做完,Laravel限流器就能按真实用户IP计数了。


















