无法从速率限制器获取实际剩余时间

问题描述 投票:0回答:1

我为登录创建了一个速率限制器,它将请求限制为每 10 分钟

n
次。如果请求已达到速率限制,我想返回一个验证异常,通知清除速率限制器之前的剩余时间。

为了简单起见,我将限制设置为

2
,如下:

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;

RateLimiter::for('login', function (Request $request) {
    $email = (string) $request->email;
    $throttle_key = str($email)->ascii()->lower().'|'.$request->ip();

    return Limit::perMinutes(10, 2)
            ->by($throttle_key)
            ->response(function () use ($throttle_key) {
                $seconds = RateLimiter::availableIn($throttle_key);

                throw ValidationException::withMessages([
                    'email' => trans('auth.throttle', [
                        'seconds' => $seconds
                    ]),
                ]);
            });
});

上面的代码正确地限制了请求:用户在 10 分钟内只有 2 次尝试尝试使用他们的电子邮件登录。但是,

RateLimiter::availableIn($throttle_key)
没有给出我上面提到的正确值。

当我第三次尝试错误登录时,

RateLimiter::availableIn($throttle_key)
只给出 1-60,而不是剩余 1 到 600 秒之间的值。经过第一分钟的衰减时间后,它总是显示
0
秒剩余,但速率限制器仍然在接下来的 9 分钟内保持请求。

请分享您想到的任何建议。非常感谢您的帮助。

laravel laravel-routing rate-limiting
1个回答
0
投票

我遇到了同样的问题,我无法评论导致新帐户,但我进行了修改并且在门面来自的

Illuminate\Cache\RateLimiter
类中做了一些转储,

显然它用一些奇怪的名字将它存储在缓存中,例如我的密钥是

'1'
并且它以加密方式将它存储在缓存中,例如
'sdkf34kfshsf:timer'
,并通过方法访问它
availableIn
是仅将
'1'
传递给缓存而不是加密值。

编辑----------------:

1 我发现的解决方法是使用标头中的值来计算剩余时间。

在响应方法的回调函数中添加headers数组。

->response(function(Request $request,array $headers) {

在“秒”行

'seconds' => $headers['Retry-After']

'seconds' => $headers['X-RateLimit-Reset'] - time()

差值应该提供剩余的秒数

© www.soinside.com 2019 - 2024. All rights reserved.