Rumah  >  Soal Jawab  >  teks badan

Pengehadan kadar untuk permintaan yang berjaya sahaja (Laravel 9)

Adakah terdapat cara untuk menggunakan had kadar pada laluan, tetapi hanya pada respons yang berjaya. Contohnya, jika pengguna menghantar permintaan ke titik akhir send/code 5 kali, jika semuanya berjaya, pengguna dihalang daripada menghantar permintaan itu semula. Walau bagaimanapun, jika 2 daripadanya gagal (seperti ralat pengesahan atau isu lain), tetapi 3 berjaya, pengguna harus mencuba 2 kali lagi dalam masa yang diberikan.

Saya tahu tentang melakukan semakan had kadar sebelum melaksanakan permintaan dan kemudian menyekat atau membiarkan pengguna meneruskan. Tetapi adakah terdapat cara untuk menggunakan logik saya atau perlukah saya mencuba pendekatan yang berbeza?

P粉807239416P粉807239416262 hari yang lalu434

membalas semua(2)saya akan balas

  • P粉986937457

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

    Ini adalah kod sumber

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

    }

    Andaikan URL saya ialah Example.com/test_Rate_Limit_only_success.

    Dalam contoh ini, apabila pengguna menghantar permintaan kepada sistem, aplikasi masih mengesahkan permintaan (jika ralat berlaku, pengguna akan menghantar permintaan tanpa had). Dengan data yang sah, bahagian mengehadkan kelajuan akan mula berfungsi.

    balas
    0
  • P粉512526720

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

    Anda mungkin perlu membuat perisian tengah anda sendiri, tetapi anda boleh melanjutkan kelas ThrottleRequests dan menyesuaikan cara anda mahu mengendalikan respons:

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

    Kemudian tambah perisian tengah anda ke Kernel.php:

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

    Kemudian gunakannya dalam laluan seperti perisian pertengahan pendikit asal:

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

    Nota: Jika anda mahu balik dari RateLimiter::for 构建的自定义响应,您可能必须重写 handleRequestUsingNamedLimiter, saya tidak melakukan apa-apa untuk itu di sini. < /p>

    balas
    0
  • Batalbalas