Laravel 接口限流实战:用 RateLimiter 防刷接口、按用户与 IP 定制配额
test12026-10-150 次阅读
为什么要限流
登录、发短信、搜索这类接口被人脚本刷起来,数据库和第三方服务先扛不住。Laravel 自带 RateLimiter,底层基于缓存(默认用 Redis),能在不写额外中间件代码的情况下按 key 限频。
在路由里直接用 throttle
// routes/api.php
use Illuminate\Support\Facades\Route;
Route::post('/login', [AuthController::class, 'login'])
->middleware('throttle:5,1'); // 每分钟最多 5 次
throttle:5,1 表示 1 分钟内最多 5 次,超出返回 429。响应头会带上 X-RateLimit-Limit 和 X-RateLimit-Remaining,前端能据此提示。
按用户区分限流 key
默认按 IP 限,但多人共享出口 IP 会误伤。用闭包自定义 key,让登录接口每人独立配额:
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)->by($request->user()?->id ?: $request->ip());
});
路由改用命名限制器:
Route::post('/login', ...)->middleware('throttle:login');
在代码里手动扣额度
有些逻辑不在路由层,比如发短信验证码,用 RateLimiter 门面手动判断:
use Illuminate\Support\Facades\RateLimiter;
$key = 'sms:' . $request->phone;
if (RateLimiter::tooManyAttempts($key, 1)) {
$seconds = RateLimiter::availableIn($key);
return response()->json(['msg' => "请 {$seconds} 秒后再试"], 429);
}
// 发送短信...
RateLimiter::hit($key, 60); // 60 秒窗口内计一次
生产建议
- 限流 key 要带业务维度(用户 ID、手机号),否则共享 IP 会集体被拦。
- 缓存必须可靠,用 Redis 而非数组或文件驱动,否则多实例下限流失效。
- 给关键写接口都加限流,读接口可放宽,别一刀切把正常流量也挡了。
T
test1
文章作者
为什么要限流 登录、发短信、搜索这类接口被人脚本刷起来,数据库和第三方服务先扛不住。Laravel 自带 RateLi...
- 分类
- 技术
- 发布时间
- 2026-10-15
- 字数
- 约 1230 字
- 阅读
- 0 次
