Ratenbegrenzung nur für erfolgreiche Anfragen (Laravel 9)
P粉807239416
P粉807239416 2024-01-05 19:47:03
0
2
485

Gibt es eine Möglichkeit, eine Ratenbegrenzung auf eine Route anzuwenden, jedoch nur bei erfolgreichen Antworten. Wenn der Benutzer beispielsweise fünfmal eine Anfrage an den send/code-Endpunkt sendet und alle erfolgreich sind, wird der Benutzer daran gehindert, die Anfrage erneut zu senden. Wenn jedoch zwei davon fehlschlagen (z. B. ein Validierungsfehler oder ein anderes Problem), drei jedoch erfolgreich sind, sollte der Benutzer es innerhalb der vorgegebenen Zeit noch zweimal versuchen.

Ich weiß, dass man vor der Ausführung der Anfrage eine Überprüfung des Ratenlimits durchführen und den Benutzer dann blockieren oder weitermachen lassen kann. Aber gibt es eine Möglichkeit, meine Logik anzuwenden, oder sollte ich einen anderen Ansatz ausprobieren?

P粉807239416
P粉807239416

Antworte allen(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,我在这里没有为此做任何事情。

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage