laravel需构建多层级限流体系:配置redis驱动并验证连接,注册全局、路由级(如登录、搜索)限流策略,启用api组中间件,暴露x-ratelimit响应头供前端监控。

面对恶意DDoS攻击,仅靠网络层清洗远远不够——应用层接口若无精细限流,极易被HTTP Flood或CC攻击拖垮数据库与PHP进程。Laravel必须构建覆盖全局、路由、用户维度的多层级限流防御体系,否则单点突破即导致服务雪崩。
配置Redis作为限流缓存驱动
打开.env文件,将CACHE_DRIVER设为redis,同时确认REDIS_HOST、REDIS_PASSWORD等配置已正确填写。
执行php artisan config:clear清除配置缓存,再运行php artisan cache:clear清空旧缓存——【若仍用file或array驱动,限流在多Worker下完全失效】。
验证是否生效:在Tinker中执行Cache::store('redis')->put('test', 'ok', 10),不报错即表示Redis连接正常。
注册全局限流策略
编辑app/Providers/RouteServiceProvider.php,在configureRateLimiting()方法内添加:
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
注意by()参数必须返回字符串,且不能含斜杠或空格;未登录用户会 fallback 到 IP,避免Call to a member function id() on null错误。
为API路由组启用限流中间件
打开app/Http/Kernel.php,检查$middlewareGroups['api']数组中是否已包含\Illuminate\Routing\Middleware\ThrottleRequests::class。
在routes/api.php中,对整个API组显式绑定策略:
Route::middleware(['api', 'throttle:api'])->group(function () { ... });
不要写成throttle:60,1硬编码形式——它会绕过RateLimiter::for()定义的策略,后续调整无法自动同步。
按业务场景定制高危接口限流
第一步:在app/Providers/AppServiceProvider.php的boot()方法中注册专用策略:
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)->by($request->ip());
});
第二步:在登录路由上单独加中间件:
Route::post('/login', [LoginController::class, 'authenticate'])->middleware('throttle:login');
第三步:对搜索类接口启用滑动窗口限流(需自定义):
RateLimiter::for('search', function (Request $request) {
return Limit::perMinutes(30, 3)->by($request->header('X-Device-ID') ?: $request->ip());
});
这一步必须确保X-Device-ID由客户端稳定提供,否则不同设备可能共享配额,造成误限。
暴露限流响应头并启用前端监控
在app/Http/Middleware/TrustProxies.php的$headers数组中追加:
ResponseHeader::HEADER_X_RATELIMIT_LIMIT,
ResponseHeader::HEADER_X_RATELIMIT_REMAINING,
ResponseHeader::HEADER_X_RATELIMIT_RESET。
编辑app/Http/Kernel.php,将\Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class替换为自定义中间件,该中间件调用response()->header()手动注入X-RateLimit-Reset时间戳。
前端可通过监听429 Too Many Requests响应,结合X-RateLimit-Reset做倒计时重试,避免暴力轮询。











