Rate limiting for successful requests only (Laravel 9)
P粉807239416
P粉807239416 2024-01-05 19:47:03
0
2
418

Is there a way to apply rate limiting to a route, but only on successful responses. For example, if a user sends requests to thesend/codeendpoint 5 times, if all are successful, the user is blocked from sending requests again. However, if 2 of them fail (e.g. validation errors or other issues), but 3 succeed, the user should try 2 more times within the given time.

I know to do a rate limit check before executing the request and then block or let the user continue. But is there a way to apply my logic or should I try a different approach?

P粉807239416
P粉807239416

reply all (2)
P粉986937457

This is the source code

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); } }

}

Suppose my URL is Example.com/test_Rate_Limit_only_success.

In this example, when the user sends a request to the system, the application still validates the request (if an error occurs, the user will send an unlimited request). With the data valid, the speed limiting part will start working.

    P粉512526720

    You may need to make your own middleware, but you can extend theThrottleRequestsclass and customize how you want to handle the 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; } }

    Then add your middleware toKernel.php:

    protected $routeMiddleware = [ // ... 'throttle.success' => ThrottleSuccess::class, // ... ];

    Then use it in routing like the original throttle middleware:

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

    NOTE: If you want to return a custom response built fromRateLimiter::foryou may have to overridehandleRequestUsingNamedLimiter, I haven't done anything for that here.

      Latest Downloads
      More>
      Web Effects
      Website Source Code
      Website Materials
      Front End Template
      About us Disclaimer Sitemap
      php.cn:Public welfare online PHP training,Help PHP learners grow quickly!