Laravel 提供了强大的内置工具来实现速率限制,防止 API 滥用,本文探讨如何有效地利用这些功能。
基础使用
Laravel 的速率限制通常使用中间件来应用。例如:
1 | Route::middleware(['auth:api', 'throttle:60,1'])->group(function () { |
/user 端点每分钟可被访问 60 次。
自定义速率限制器
在一些复杂的场景,需要自定义速率限制器,在 AppServiceProvider 中定义或者使用特定的服务提供者(Service Provider)。下面示例在 AppServiceProvider 的 boot 方法中定义:
1 | use Illuminate\Cache\RateLimiting\Limit; |
应用:
1 | Route::middleware(['throttle:api'])->group(function () { |
动态速率限制
例如你可以更具用户角色或者订阅级别设置速率:
1 | RateLimiter::for('premium', function (Request $request) { |
高级用户比普通用户有更多的调用次数。
全局限制 vs 特定路由限制
在 app/Http/Kernel.php 中设置全局限制:
1 | protected $middlewareGroups = [ |
或者对特定路由限制:
1 | Route::post('/login', [AuthController::class, 'login']) |
处理速率限制异常
当调用次数超过限制频率, Laravel 抛出 Illuminate\Http\Exceptions\ThrottleRequestsException 异常。Laravel 11 之前的版本在 app/Exceptions/Handler.php 捕获:
1 | public function render($request, Throwable $exception) |
进阶用法:
滑动窗口速率限制(Sliding Window Rate Limiting)
想要更加精细的控制,可以使用 Sliding Window Rate Limiting:
1 | RateLimiter::for('sliding', function (Request $request) { |
使用 Redis 实现速率限制(Rate Limiting with Redis)
对于高流量的应用,使用 Redis 实现速率限制。
1 | RateLimiter::for('redis', function (Request $request) { |
组合使用
1 | Route::middleware(['throttle:global,throttle:api'])->group(function () { |
参考:
https://www.harrisrafto.eu/securing-your-laravel-apis-with-built-in-rate-limiting/