主页/PHP笔记/PHP问答/框架Laravel/如何在 Laravel 中实现限流

如何在 Laravel 中实现限流

Bug编译狮

Bug编译狮

在 Laravel 中实现限流(Rate Limiting)可以通过多种方式实现,其中最常用的是使用 IlluminateRoutingMiddlewareThrottleRequests 中间件。这个中间件可以帮助你在应用的各个路由中设置请求速率限制。

1. 安装和配置 Throttle Requests

首先,你需要安装 throttlerequests 包:

composer require laravel/traffic

然后,将这个包添加到你的服务提供者中:

// config/app.php
'providers' => [
    // ...
    AppProvidersTrafficServiceProvider::class,
],

接下来,运行以下命令来发布配置文件并创建数据库表:

php artisan vendor:publish --provider="AppProvidersTrafficServiceProvider"
php artisan migrate

2. 创建自定义限流规则

你可以根据需要创建自定义限流规则。例如,如果你想对每个 IP 地址每分钟只允许访问一次,可以这样做:

use IlluminateSupportFacadesRateLimiter;

RateLimiter::for('ip', function ($request) {
    return $request->ip();
}, 60);

3. 使用 Throttle Requests 中间件

在你的控制器方法上使用 throttle 方法来应用限流规则:

namespace AppHttpControllers;

use IlluminateHttpRequest;
use IlluminateSupportFacadesRateLimiter;

class ExampleController extends Controller
{
    public function index(Request $request)
    {
        RateLimiter::for('ip', function ($request) {
            return $request->ip();
        }, 60);

        if (RateLimiter::tooManyAttempts('ip', 5)) {
            return response()->json(['message' => 'Too many attempts'], 429);
        }

        // 处理请求逻辑
        return response()->json(['message' => 'Request processed']);
    }
}

4. 示例代码步骤

4.1 创建自定义限流规则

// app/Routes/web.php
Route::get('/example', [ExampleController::class, 'index'])->middleware('throttle:ip,60');

4.2 配置 Throttle Requests 中间件

// config/traffic.php
return [
    'limits' => [
        'ip' => [
            60 => 5, // 每个 IP 地址每分钟最多 5 次请求
        ],
    ],
];

4.3 测试限流

打开浏览器并访问 /example 路由,如果 IP 地址已经超过了 5 次请求,则会收到 429 状态码。

通过以上步骤,你可以在 Laravel 中成功实现限流功能。你可以根据具体需求调整限流规则和参数。

黑板Bug讲师

黑板Bug讲师

概览

Laravel 是最灵活且功能强大的PHP框架之一,它自带强大特性。其中一项重要功能就是限流能力,可以帮助保护API免受过多请求的冲击。本教程将指导您在Laravel应用中实现限流功能。

理解限流(Rate Limiting)

API开发和维护中,限流(rate limiting)是一项至关重要的方面。它确保应用在指定的时间范围内能够处理一定数量的请求。这不仅防止滥用行为,还能帮助保持所有用户对API的性能和可用性。

设置中间件

在Laravel中,限流功能通过中间件实现。Laravel中的中间件提供了一个方便的机制来过滤进入应用程序的HTTP请求。

为了开始,导航到app/Http/Kernel.php文件。在这里,您将在限流中间件中定义您的速率限制中间件。

路由中间件数组:

protected $ routeMiddleware = [
    'auth' => AppHttpMiddlewareAuthenticate::class,
    // ...
    'throttle' => IlluminateRoutingMiddlewareThrottleRequests::class,
];

这是默认的。throttle中间件使用Laravel缓存来跟踪用户在一定时期内发出的请求数量。

限流路由

为了应用限流策略到路由,您需要在要限制的路由或一组路由上使用中间件方法。

Route::middleware('throttle:60,1')->group(function () {
    Route::get('/my-api', 'ApiController@index');
    // Add your rate limited routes here
});

上述代码片段告诉Laravel允许每分钟最多60次请求(即每秒一次请求)。/my-api路线。

自定义速率限制

在需要为不同路由定义不同限流规则的情况下,你可以自己定义。

use IlluminateRoutingMiddlewareThrottleRequests;

Route::middleware('throttle:100,5')->group(function () {
    Route::get('/another-api', 'AnotherApiController@index');
});

这设置了每五分钟内请求的最大限制为一百次。

创建自己的中间件

如果默认的节流设置不符合您的需求,您可以创建自定义中间件。

php artisan make:middleware CustomThrottleMiddleware

创建好中间件后,需要在HTTP核中注册它:

protected $ routeMiddleware = [
    // ...
    'customThrottle' => AppHttpMiddlewareCustomThrottleMiddleware::class,
];

在定制实现中,你可以操纵请求或自定义用于计算限流逻辑。

动态速率限制

Laravel 允许您实现动态速率限制,该限制会根据已认证的用户进行调整:

Route::middleware(['auth', 'throttle:rate_limit,1'])->group(function () {
    // Protected routes here
});


// In 'AppServiceProvider':
public function boot()
{
    RateLimiter::for('rate_limit', function (Request $request) {
        return Limit::perMinute(100)->by(optional($request->user())->id ?: $request->ip());
    });
}

在这一例子中,您定义了rate_limit根据用户的ID或如果他们未认证则使用IP地址,为每位用户提供独特的体验。

错误处理和响应

当限流被超过时,429 Too Many RequestsHTTP状态码返回了。可以通过重写此行为来自定义这种行为,通过覆盖。handle在你的 throttle 中间件方法中:

public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1)
{
    // Custom logic here
}

实施基于Laravel API资源的速率限制

在Laravel的API资源上实施速率限制是一个简单的过程,可以非常有效地通过Laravel内置功能来管理。这里有一个简单的例子来说明如何在Laravel中实现API的速率限制。

步骤1:定义路线

首先,你需要定义你的API端点。这通常是在代码中实现的。routes/api.php文件。

use AppHttpControllersApiUserController;

Route::apiResource('users', UserController::class);

步骤 2:使用中间件进行限流处理

Laravel 提供了一个throttle限流中间件(middleware for rate limiting)。你可以将此中间件应用于你的路由,以限制用户在特定时间范围内可以发出的请求数量。

你可以选择直接应用中间件到一个路由或一组路由:

Route::middleware('throttle:60,1')->apiResource('users', UserController::class);

在这一例子中,throttle:60,1每分钟最多允许发出60个请求。

步骤 3:自定义速率限制

如果您需要更多的控制,您可以定义速率限制逻辑。Kernel.php文件位于。app/Http目录。

对不起,您的消息没有接收到。请重新尝试。$routeMiddleware抱歉,我不太明白您的意思,请重新描述您需要翻译的内容。Kernel.php您可以通过添加自定义节流键来添加您的自定义节流键:

protected $routeMiddleware = [
    // ...
    'customThrottle' => IlluminateRoutingMiddlewareThrottleRequests::class,
];

然后在路由中使用它:

Route::middleware('customThrottle:requestsPerMinute,decayMinutes')->apiResource('users', UserController::class);

第4步:处理超时异常

当用户超出了速率限制时,Laravel 会抛出一个错误。ThrottleRequestsException您可以自定义此异常响应,通过编辑。render方法。AppExceptionsHandler已经收到消息。

public function render($request, Throwable $exception)
{
    if ($exception instanceof IlluminateHttpExceptionsThrottleRequestsException) {
        return response()->json(['message' => 'Too many requests, please slow down.'], 429);
    }

    return parent::render($request, $exception);
}

步骤5:测试您的API

现在,你可以使用工具如Postman或cURL来测试API,以确保限流功能正常工作。向API端点发送请求并验证,在设定的限制后,API会返回状态码429。

请记住,适当的速率限制值取决于您的具体应用需求和服务器能力。根据需要进行相应的调整以实现最佳性能和用户体验。

结论。

限流是一项至关重要的功能,用于确保应用程序的持久性和可靠性。Laravel内置的限流服务提供了一个强大的且灵活的系统。记住,正确实施限流的关键在于理解API的使用模式,并根据需要调整限制以保持可访问性和保护之间的平衡。

请记住,这里使用的技术也可以进一步扩展和定制以满足您的特定需求。随着应用程序的增长,请始终审查并调整速率限制设置,以确保最佳性能和安全性。

长工码奴1523

长工码奴1523

在 Laravel 中实现限流功能可以通过使用 Eloquent ORM 的缓存机制来实现。以下是一个简单的例子:

  1. 首先,确保你已经安装了 Eloquent ORM 和 Redis。

  2. 在控制器中添加缓存的钩子:

use IlluminateContractsCacheRepository;
use IlluminateHttpRequest;

public function __construct(Repository $cache)
{
    $this->cache = $cache;
}

protected function cacheResponse(Response $response, Request $request)
{
    // 缓存响应
    $response->headers->set('Cache-Control', 'max-age=600');
    $this->cache->forever($request->fullUrl(), $response);
}
  1. 为每个需要限流的方法添加缓存钩子,并设置相应的缓存时间(例如:600 秒):
Route::get('/api/{endpoint}', [YourControllerName::class, 'yourMethod'])->middleware(['throttle:your_rate_limit'])->name('your_method');

// 示例:限流到每分钟 5 次
function yourMethod(Request $request) {
    if ($request->has('limit')) {
        return response()->json(['message' => 'Rate limit exceeded'], 429);
    }
    // 其他业务逻辑...
}

在这个例子中,throttle:your_rate_limit 是限流的中间件,它会检查请求是否达到速率限制。如果达到了速率限制,则返回一个 JSON 响应表示速率限制已超时。

此外,为了防止缓存过期导致的性能问题,可以考虑将缓存时间设置得更长一些。但是请注意,缓存时间过长可能导致数据库访问频繁的问题。

以上就是一个基本的限流实现,你可以根据具体需求调整速率限制和缓存策略。