仅成功请求的速率限制 (Laravel 9)
P粉807239416
P粉807239416 2024-01-05 19:47:03
0
2
480

是否有办法对路线应用速率限制,但仅限于成功响应。例如,如果用户向 send/code 端点发送请求 5 次,如果全部成功,则阻止用户再次发送请求。但是,如果其中 2 次失败(例如验证错误或其他问题),但 3 次成功,则用户应该在给定时间内再尝试 2 次。

我知道在执行请求之前进行速率限制检查,然后阻止或让用户继续。但是有没有办法应用我的逻辑,或者我应该尝试不同的方法?

P粉807239416
P粉807239416

全部回复(2)
P粉986937457

这是源代码

use Illuminate\Support\Facades\RateLimiter;

class CodeZiDotProTestRateLimit extends Controller{
public function test_rate_limit_only_success(Request $request){

    // Step 1: Validate the request data
    $validator = Validator::make($request->all(), [
        'name' => 'required|string',
        'email' => 'required|email',
        'password' => 'required|min:8',
    ]);

    if ($validator->fails()) {
        return response()->json(['errors' => $validator->errors()], 422);
    }

    // Step 2: Apply rate limiting to this controller action
    $key = 'test_rate_limit_only_success_by_ip_'.request()->ip();
    if (RateLimiter::tooManyAttempts($key,10)) {
        return response()->json(['errors' => 'You have made too much in a short time. Please wait after 1 minute'], 422);
    } else {
        RateLimiter::hit($key, 60);
    }
}

}

假设我的网址是 Example.com/test_Rate_Limit_only_success。

在此示例中,当用户向系统发送请求时,应用程序仍会验证该请求(如果出现错误,用户将发送无限制的请求)。在数据有效的情况下,限速部分将开始工作。

P粉512526720

您可能需要制作自己的中间件,但您可以扩展 ThrottleRequests 类并自定义您想要处理响应的方式:

<?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,
        // ...
    ];

然后像原来的throttle中间件一样在路由中使用它:

Route::middleware('throttle.success:5,1')->group(function () {
    // ...
});

注意:如果您想返回从 RateLimiter::for 构建的自定义响应,您可能必须重写 handleRequestUsingNamedLimiter,我在这里没有为此做任何事情。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板