搜尋

首頁  >  問答  >  主體

僅成功請求的速率限制 (Laravel 9)

是否有辦法對路線套用速率限制,但僅限於成功回應。例如,如果使用者向 send/code 端點發送請求 5 次,如果全部成功,則阻止使用者再次發送請求。但是,如果其中 2 次失敗(例如驗證錯誤或其他問題),但 3 次成功,則使用者應該在給定時間內再嘗試 2 次。

我知道在執行請求之前進行速率限制檢查,然後阻止或讓使用者繼續。但是有沒有辦法應用我的邏輯,或者我應該嘗試不同的方法?

P粉807239416P粉807239416447 天前579

全部回覆(2)我來回復

  • P粉986937457

    P粉9869374572024-01-06 17:02:10

    這是原始碼

    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。

    在此範例中,當使用者向系統發送請求時,應用程式仍會驗證該請求(如果發生錯誤,使用者將發送無限的請求)。在數據有效的情況下,限速部分將開始工作。

    回覆
    0
  • P粉512526720

    P粉5125267202024-01-06 09:10:49

    您可能需要製作自己的中間件,但您可以擴展 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,我在這裡沒有為此做任何事情。 < /p>

    回覆
    0
  • 取消回覆