Laravel API 速率限制需显式配置 throttle 中间件,如 throttle:60,1;默认按 IP 限流,登录用户需确保 auth:sanctum 在 throttle 前执行;自定义策略应于 RouteServiceProvider 中定义并指定 by() 键;生产环境必须使用 Redis 缓存驱动。
直接在 Laravel 中用
中间件就能实现 API 速率限制,无需额外包。关键在于
路由
定义时的参数组合和自定义限流策略的时机。
如何在 API 路由中启用 throttle 中间件
Laravel 默认已为
路由组注册了
,但这个策略实际是空的(Laravel 9+),必须手动配置或替换。最常用做法是显式指定中间件参数:
表示每分钟最多 60 次请求
表示每 5 分钟最多 100 次
参数顺序固定:请求数量,时间窗口(单位:分钟)
该中间件默认按客户端 IP 限流;如需按用户 ID 或 API token 区分,需自定义
为什么匿名用户被限流而登录用户没效果?
因为默认
实现使用
作为 key 基础,对所有未认证请求一视同仁。而登录用户若走的是
guard 且未在中间件中显式切换识别逻辑,仍可能 fallback 到 IP —— 尤其当你的认证是通过
但未启用
类中间件时。
确保 API 认证中间件(如
)在
之前执行
否则
取不到值,限流 key 退化为 IP
正确顺序示例:
如何按用户 ID 或 API token 限流(而非 IP)
需要重写限流 key 的生成逻辑。Laravel 允许在
的
方法中注册自定义策略:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
然后在路由中使用:
。注意:
的值必须是字符串,且不能含特殊字符;若用 token,建议取
再截断。
常见错误:429 响应体不包含 Retry-After 或 X-RateLimit 头
这是因你用了非标准响应格式(比如全局返回 JSON 的异常
处理器
覆盖了 Laravel 原生
的响应逻辑)。原生中间件会在响应头中自动添加:
:窗口内最大请求数
:剩余可请求数
:秒级等待时间(仅当超出时)
若这些头缺失,检查是否在
中误捕获了
并返回了无头响应
真正容易被忽略的是:缓存驱动必须支持原子计数(如 Redis),否则
或
缓存在高并发下会漏限流。生产环境务必确认
且连接正常。
throttleapithrottle:apithrottle:60,1throttle:100,5throttle$request->ip()apiAuthorization: Bearer xxxEnsureTokenIsValidauth:sanctumthrottleAuth::id()middleware(['auth:sanctum', 'throttle:30,1'])app/Providers/RouteServiceProvider.phpconfigureRateLimitinguse Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
RateLimiter::for('api_by_user', function (Request $request) {
return $request->user()
? Limit::perMinute(60)->by($request->user()->id)
: Limit::perMinute(10)->by($request->ip());
});middleware('throttle:api_by_user')by()hash_hmac('sha256', $token, config('app.key'))ThrottleRequestsX-RateLimit-LimitX-RateLimit-RemainingRetry-AfterApp\Exceptions\Handler.phpThrottleRequestsExceptionfiledatabaseCACHE_DRIVER=redis