namespace App\Providers;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
RateLimiter::for('weather', function(Request $request) {
return Limit::perMinute(5)
->by($request->user()?->id ?: $request->ip());
});
}
}
这段代码是一个 Laravel 项目中的服务提供者(ServiceProvider)代码,具体实现了一个限流(Rate Limiting)功能。下面是对这段代码的详细解释:
代码解析
- boot 方法
boot 方法是服务提供者中的一个特殊方法,当所有服务提供者都注册之后,该方法会自动调用。 通常用来注册事件监听器,或者是其他框架初始化工作。 - 限流逻辑
RateLimiter::for('weather', function(Request $request) { return Limit::perMinute(5) ->by($request->user()?->id ?: $request->ip()); });RateLimiter::for('weather'...:定义了一个名为 weather 的速率限制器。return Limit::perMinute(5):设置这个操作每分钟只能执行 5 次。->by($request->user()?->id ?: $request->ip()):限流依据是用户 ID,如果用户未登录(即没有用户 ID),则使用用户的 IP 地址进行限流。
作用
这段代码的作用是防止用户频繁请求 weather 接口。每个用户每分钟最多只能请求 5 次这个接口。如果用户未登录,则基于 IP 地址进行限流。这种机制可以有效防止接口被滥用,保护服务器资源。
注意事项
- 如果需要对 weather 接口进行更细粒度的限流,可以调整
perMinute(5)中的数值。 - 这段代码中的
$request->user()?->id使用的是 PHP 8.0 引入的安全访问运算符(nullsafe operator),确保即使$request->user()返回null,也不会引发错误。 - 确保 RateLimiter 和 Limit 已正确引入,通常情况下它们在
Illuminate\Support\Facades\RateLimiter和Illuminate\Cache\RateLimiting\Limit中。
通过设置合适的限流规则,可以有效保护 API 免受滥用,同时也能保证合法用户的正常使用。
如何使用
要在 Laravel 应用中使用限流逻辑,可以按照以下步骤进行配置和使用。以下是详细的步骤说明:
1. 更新 AppServiceProvider 文件
首先,需要在 AppServiceProvider 中定义限流逻辑。确保你已经将限流逻辑添加到 boot 方法中,如之前提到的那。
2. 使用限流逻辑
接下来,你需要在路由或控制器中应用这个限流逻辑。假设你有一个天气接口,你可以在路由中使用中间件来应用限流。
2.1 在路由中应用限流
在 routes/web.php 或 routes/api.php 中,你可以使用 throttle 中间件来应用限流。
use Illuminate\Support\Facades\Route;
Route::middleware(['throttle:weather'])->group(function () {
Route::get('/weather', 'WeatherController@getWeather');
});
2. 在控制器中应用限流
如果你想在控制器中直接应用限流,可以在控制器方法中使用 throttle 中间件:
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Http\Request;
class WeatherController extends BaseController
{
public function __construct()
{
$this->middleware('throttle:weather');
}
public function getWeather(Request $request)
{
// 获取天气数据的逻辑
return response()->json(['weather' => 'sunny']);
}
}
3. 配置 throttle 中间件
在 app/Http/Kernel.php 文件中,确保 throttle 中间件已注册:
protected $routeMiddleware = [
// 其他中间件
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
4. 测试限流逻辑
通过访问 /weather 接口进行测试,每分钟超过 5 次请求时,应该会返回 HTTP 429 错误(Too Many Requests)。
5. 自定义错误响应(可选)
你可以自定义限流超出后的错误响应。在 app/Exceptions/Handler.php 中重写 prepareResponse 方法:
protected function prepareResponse($request, Throwable $e)
{
if ($e instanceof \Illuminate\Http\Exceptions\ThrottleRequestsException) {
return response()->json(['error' => 'Too Many Requests'], 429);
}
return parent::prepareResponse($request, $e);
}
总结
通过上述步骤,你可以在 Laravel 应用中实现并使用限流逻辑,以防止用户过于频繁地访问某些接口。限流机制可以有效保护你的应用免受滥用,同时保证服务的稳定性和可用性。
