Laravel 8 Fortify 登录显示 429 太多请求

我遇到了与 429 TOO MANY REQUESTS 相关的问题。我使用了 Laravel fortify,我的网络路由就像

Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard','DashboardController@dashboardView')
    ->name('dashboard')->middleware('auth');

问题间歇性地出现,成功登录后,如果我立即退出并立即尝试登录,我会重定向到仪表板,它会给出 429 TOO MANY REQUESTS 并且在地址栏中的 URL 是 http://127.0.0.1:8000/login 。现在,如果我在那里等待一秒钟并刷新页面,它会重定向到仪表板页面。

我在网上搜索过,每个人都在说油门,我不认为这是解决方案。请帮我。谢谢。

stack overflow Laravel 8 Fortify login says 429 TOO MANY REQUESTS
原文答案
author avatar

接受的答案

我今天偶然发现了同样的问题并进行了一些调试。注册 /login 路由时,Fortify 将 IlluminateRoutingMiddlewareThrottleRequests:login 中间件应用到它。这意味着,对于对该路由的每个请求, ThrottleRequests 中间件将为该指定键调用 RateLimiter 实例。显然,Fortify 没有为 RateLimiter 键注册 login

由于 $limiters 实例的 RateLimiter 属性中缺少键, ThrottleRequests 中间件使用其默认的回退,它不处理边缘情况“应该有该键的速率限制器,但没有。”真的很好。 $maxAttempts 变量设置为 0,将导致不稳定的速率限制行为。

我觉得这是 Fortify 中的一个错误,因为在 LaravelFortifyActionsEnsureLoginIsNotThrottled 控制器中调用的 LaravelFortifyHttpControllersAuthenticatedSessionController 操作中也发生了速率限制。不过,我没有在全新的 Laravel 安装上检查这一点,所以我不想在这里草率下结论。

无论如何,长话短说:作为一种解决方法,您可以简单地在某些提供商中为“登录”键注册一个速率限制器,例如。 G。 AppServiceProviderAuthServiceProvider

public function boot()
{
    RateLimiter::for("login", function () {
        Limit::perMinute(5);
    });
}

编辑: 我刚刚意识到 Fortify 在 FortifyServiceProvider 类中确实提供了“登录”键的速率限制器。如果您碰巧遇到与上述问题类似的问题,请确保将 FortifyServiceProvider 类添加到 providers 中的 config/app.php 数组中。


答案:

作者头像

我尝试了所有方法,包括最佳答案,但它没有奏效。

因此,甚至不更改 RateLimiter 类中的 FortifyServiceProvider

我会尝试登录并得到一个 429 错误在一次登录尝试后

这对我来说是什么问题,它是 config/fortify.php 文件。

我不得不改变:

    /*
    |--------------------------------------------------------------------------
    | Rate Limiting
    |--------------------------------------------------------------------------
    |
    | By default, Fortify will throttle logins to five requests per minute for
    | every email and IP address combination. However, if you would like to
    | specify a custom rate limiter to call then you may specify it here.
    |
    */

    'limiters' => [
        'login' => 'login',
        'two-factor' => 'two-factor',
    ],

    /*
    |--------------------------------------------------------------------------
    | Rate Limiting
    |--------------------------------------------------------------------------
    |
    | By default, Fortify will throttle logins to five requests per minute for
    | every email and IP address combination. However, if you would like to
    | specify a custom rate limiter to call then you may specify it here.
    |
    */

    'limiters' => [
        'login' => 5,
        'two-factor' => 5,
    ],

有趣的是,当您运行时,问题是 Fortify 包本身固有的:

php artisan vendor:publish --provider="LaravelFortifyFortifyServiceProvider" 根据他们的 documentation instructions

这个根本原因是 vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php 中的代码无法正确解析限制:

    /**
     * Resolve the number of attempts if the user is authenticated or not.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  int|string  $maxAttempts
     * @return int
     */
    protected function resolveMaxAttempts($request, $maxAttempts)
    {
        if (Str::contains($maxAttempts, '|')) {
            $maxAttempts = explode('|', $maxAttempts, 2)[$request->user() ? 1 : 0];
        }

        if (! is_numeric($maxAttempts) && $request->user()) {
            $maxAttempts = $request->user()->{$maxAttempts};
        }

        return (int) $maxAttempts;
    }

,这意味着 'login' 只是被解析为 0 并且这就是它返回的内容。

现在我不必为了测试而运行 php artisan cache:clear

作者头像

app/http/kernel.php

并从 routeMiddleware 列表中删除该行

'cache.headers' => IlluminateHttpMiddlewareSetCacheHeaders::class,