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

是否有辦法對路線套用速率限制,但僅限於成功回應。例如,如果使用者向 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,我在這裡沒有為此做任何事情。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!