[英]Rate Limit for only success requests (Laravel 9)
无论如何对路由应用速率限制但仅用于成功响应。 例如,如果用户向send/code
端点发送请求 5 次,如果所有这些都成功,则阻止用户再次发送请求。 但是,如果其中 2 次不成功(例如验证错误或其他原因)但 3 次成功,则用户应该在给定时间内再尝试 2 次。
我知道在执行请求之前进行速率限制检查,然后阻止或让用户继续。 但是无论如何应用我的逻辑还是我应该尝试不同的方法?
您可能需要制作自己的中间件,但您可以扩展ThrottleRequests
class 并自定义您想要处理响应的方式:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Support\Arr;
class ThrottleSuccess extends ThrottleRequests
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param array $limits
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Illuminate\Http\Exceptions\ThrottleRequestsException
*/
protected function handleRequest($request, Closure $next, array $limits)
{
$response = $next($request); // call the controller first
if ($response->statusCode === 200) { // only hit limiter on successful response
foreach ($limits as $limit) {
if ($this->limiter->tooManyAttempts($limit->key, $limit->maxAttempts)) {
throw $this->buildException($request, $limit->key, $limit->maxAttempts, $limit->responseCallback);
}
$this->limiter->hit($limit->key, $limit->decayMinutes * 60);
}
}
foreach ($limits as $limit) {
$response = $this->addHeaders(
$response,
$limit->maxAttempts,
$this->calculateRemainingAttempts($limit->key, $limit->maxAttempts)
);
}
return $response;
}
}
然后将您的中间件添加到Kernel.php
:
protected $routeMiddleware = [
// ...
'throttle.success' => ThrottleSuccess::class,
// ...
];
然后像原来的油门中间件一样在路由中使用它:
Route::middleware('throttle.success:5,1')->group(function () {
// ...
});
注意:如果你想返回从RateLimiter::for
构建的自定义响应,你可能必须重写handleRequestUsingNamedLimiter
,我在这里没有做任何事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.