laravel 项目中可直接使用内置 throttle 中间件实现 api 限流,支持 redis 滑动窗口、跨服务器一致性及数据库后备;基础用法为 throttle:60,1,区分游客与登录用户需自定义 throttle_key,还可通过 ratelimiter 定义命名限流器或手动调用 toomanyattempts/hit 进行细粒度控制。

要在 Laravel 项目中快速实现 API 请求限流,防止暴力刷接口或爬虫高频调用,直接使用框架自带的 throttle 中间件即可,无需手写计数器或引入第三方包——它底层已通过 Redis 实现滑动窗口,支持跨服务器一致性和防穿透,且默认启用数据库后备机制。
基础限流:单 IP 每分钟最多 60 次
打开 routes/api.php,在目标路由后追加中间件参数:
Route::get('/posts', [PostController::class, 'index'])->middleware('throttle:60,1');
这行代码表示:对所有访问 /posts 的请求,按客户端 IP 地址做限流,每分钟最多放行 60 次。超限后返回 HTTP 429 状态码,并自动携带 Retry-After 响应头。
注意:该规则依赖 cache 配置,默认走 redis store;若本地开发用 array 驱动,限流将不生效——【上线前必须确认 .env 中 CACHE_DRIVER=redis 且 REDIS_HOST 可连通】。
区分游客与登录用户的差异化限流
第一步:在 app/Http/Middleware 下新建中间件:
php artisan make:middleware EnsureThrottleKeyIsSet
第二步:编辑该文件,在 handle 方法中动态设置请求属性:
$request->attributes->set('throttle_key', $request->user() ? 'user_'.$request->user()->id : 'guest_'.($request->ip() ?: 'unknown'));
第三步:在路由定义中引用该中间件并绑定 throttle:
->middleware(['ensure.throttle.key.is.set', 'throttle:10,1|100,1,by=throttle_key'])
这里用竖线分隔两组规则:游客(IP)每分钟 10 次,登录用户(ID)每分钟 100 次;by=throttle_key 告诉 throttle 使用我们刚设的自定义键,而非默认的 IP。
命名式限流器:复用规则 + 多维度叠加
方法一:在 app/Providers/AppServiceProvider.php 的 boot 方法中定义:
RateLimiter::define('uploads', function (Request $request) { return [ Limit::perMinute(3), Limit::perHour(20)->by($request->ip()) ]; });
方法二:将命名限流器绑定到路由分组:
Route::middleware('throttle:uploads')->group(function () { Route::post('/upload', [UploadController::class, 'store']); });
这个例子同时施加两个限制:每分钟最多 3 次上传,且每小时累计不超过 20 次——两者独立计数,任一触发即拦截。短时突发允许,长期总量可控。
手动触发限流校验:用在非路由场景
比如密码重置接口需限制单 IP 每小时最多 5 次尝试:
$key = 'password-reset:' . $request->ip(); if (RateLimiter::tooManyAttempts($key, 5)) { $seconds = RateLimiter::availableIn($key); return response()->json(['message' => "请 {$seconds} 秒后重试"], 429); } RateLimiter::hit($key, 3600);
这三行代码完成判断→返回提示→计数递增全过程;hit 的第二个参数是锁定时长(秒),超时后计数自动清零。











