Laravel-Praxis, Redis nur zur Strombegrenzung in der Produktionsumgebung zu verwenden
P粉541565322
P粉541565322 2024-01-10 17:54:47
0
1
453

Hintergrund

Standardmäßig stellt Laravel zwei Middlewares zur Ratenbegrenzung (Drosselung) bereit:

\Illuminate\Routing\Middleware\ThrottleRequests::class
\Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class

Wie in der Dokumentation angegeben, können Sie die Zuordnung in Kernel.php wie folgt ändern, wenn Sie Redis als Cache-Treiber verwenden:

/**
 * 应用程序的中间件别名。
 *
 * 别名可用于将中间件方便地分配给路由和组,而不是使用类名。
 *
 * @var array<string, class-string|string>
 */
protected $middlewareAliases = [
    // ...
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class
    // ...
];

Frage

Das Problem besteht darin, dass das oben Genannte nicht dynamisch, sondern umgebungsabhängig ist. In meiner stagingproduction环境中,我使用Redis,但在我的localdevelopmentUmgebung verwende ich beispielsweise kein Redis.

Mögliche Lösungen

Es gibt eine offensichtlich schmutzige Lösung, etwa diese (Kernel.php):

/**
 * 应用程序的中间件别名。
 *
 * 别名可用于将中间件方便地分配给路由和组,而不是使用类名。
 *
 * @var array<string, class-string|string>
 */
protected $middlewareAliases = [
    // ...
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class
    // ...
];

/**
 * 创建一个新的HTTP内核实例。
 *
 * @param  \Illuminate\Contracts\Foundation\Application  $app
 * @param  \Illuminate\Routing\Router  $router
 * @return void
 */
public function __construct(Application $app, Router $router)
{
    if ($app->environment('production')) {
        $this->middlewareAliases['throttle'] = \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class;
    }

    parent::__construct($app, $router);
}

Gibt es eine „Standard“-Methode, um relevante Middleware dynamisch auszuwählen, ohne sie zu überschreiben Kernel构造函数的情况下实现这一点?基本上,我希望我的应用程序可以根据环境是否设置为production(或者默认缓存存储设置为redis).

Update

Die obige Lösung funktioniert nicht, da auf den Kernel zugegriffen wird, bevor die Anwendung gestartet wird, sodass die Umgebung derzeit nicht verfügbar ist. Eine andere Lösung, die ich derzeit in Betracht ziehe, besteht darin, die Basisklasse ThrottleRequests so zu erweitern, dass die relevanten Klassen dynamisch aufgerufen werden können.

P粉541565322
P粉541565322

Antworte allen(1)
P粉043432210

经过大量的研究和测试,我得出的结论是在RouteServiceProvider中动态设置throttle中间件是最好的解决方案,代码如下:

class RouteServiceProvider extends ServiceProvider
{
    /**
     * 启动任何应用程序服务。
     *
     * @return void
     */
    public function boot(): void
    {
        $this->registerThrottleMiddleware();
    }

    /**
     * 注册用于限制请求的中间件。
     *
     * @return void
     */
    private function registerThrottleMiddleware(): void
    {
        $router = app()->make('router');

        $middleware = config('cache.default') !== 'redis'
            ? \Illuminate\Routing\Middleware\ThrottleRequests::class
            : \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class;

        $router->aliasMiddleware('throttle', $middleware);
    }
}
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage