在 Laravel 中防止接口被恶意刷请求,最稳妥的做法是使用框架内置的速率限制中间件,并配合 Redis 缓存驱动实现分布式计数。
先说结论:直接启用 Laravel 自带的 throttle 中间件,并将缓存驱动配置为 Redis 以确保多实例环境下计数准确。
- 先判断:确认你的应用是否部署在多台服务器或使用了负载均衡,这决定了是否需要共享缓存。
- 优先做:在路由组或特定接口上绑定 throttle 中间件,并定义合理的限制规则。
- 再验证:通过脚本连续发送请求,观察是否返回 429 状态码。
实施步骤
核心是在路由定义中添加中间件,并确保缓存驱动支持共享。以下是具体配置流程。
第一步:配置缓存驱动
检查 .env 文件,确保缓存存储设置为 redis。Laravel 9+ 及 11 版本推荐使用 CACHE_STORE 变量,旧版本可能使用 CACHE_DRIVER。
CACHE_STORE=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379修改后需执行 php artisan config:clear 使配置生效。
第二步:定义速率限制规则
需要在应用启动时注册限制器。在 Laravel 8-10 中,通常在 RouteServiceProvider 的 boot 方法里;在 Laravel 11 中,由于移除了 RouteServiceProvider,建议在 AppServiceProvider 的 boot 方法或 bootstrap/app.php 中通过 withMiddleware 配置。
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Http\Request;
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});这段代码优先按用户 ID 限制,未登录用户则按 IP 限制。
第三步:应用中间件
在路由上使用刚才定义的 limiter 名称。Laravel 默认提供了 throttle:api,也可以自定义名称。
Route::middleware(['throttle:api'])->group(function () {
// 你的受保护接口
Route::get('/user', [UserController::class, 'show']);
});验证方法
不要只用浏览器刷新,因为浏览器可能会缓存或有其他干扰。使用 curl 或 Postman 进行压力测试。
检查命令:
# 循环发送 70 次请求,观察后 10 次是否被拒绝
for i in {1..70}; do curl -w "%{http_code}\n" -o /dev/null -s http://your-domain.com/api/test; done状态判断:
前 60 次请求应该返回 200 状态码,之后的请求应该返回 429 状态码。同时检查响应头中是否包含 X-RateLimit-Limit 和 X-RateLimit-Remaining 字段,这些字段能告诉客户端剩余配额。
常见坑
1. 负载均衡后的 IP 识别问题
如果应用部署在 Nginx 或其他负载均衡器后面,$request->ip() 获取的可能是内网 IP,导致所有用户被当成同一个 IP 限制。需要配置信任代理。
在 Laravel 8-10 中,确保 App\Http\Middleware\TrustProxies 中间件已启用并配置 $proxies 属性。在 Laravel 11 中,通常在 bootstrap/app.php 中通过 withMiddleware 方法配置信任代理,例如:$middleware->trustProxies(at: '*'),以便框架能读取 X-Forwarded-For 头获取真实用户 IP。
2. 缓存驱动不一致
开发环境常用 file 或 array 驱动,生产环境用 Redis。如果代码中硬编码了依赖特定缓存行为的逻辑,部署后可能失效。务必在 .env 中区分环境配置,并确保生产环境 CACHE_STORE 不为 array。
3. 静态资源被误伤
不要对全站开启严格的频率限制,尤其是 CSS、JS 和图片请求。建议只对 API 路由组或特定的 Web 接口组应用 throttle 中间件,避免影响正常页面加载。
参考来源
- Laravel Official Documentation - Rate Limiting, URL: https://laravel.com/docs/routing#rate-limiting
- Laravel Official Documentation - Cache Configuration, URL: https://laravel.com/docs/cache