59 lines
1.8 KiB
PHP
59 lines
1.8 KiB
PHP
<?php
|
|
|
|
namespace DanHarrin\LivewireRateLimiting;
|
|
|
|
use DanHarrin\LivewireRateLimiting\Exceptions\TooManyRequestsException;
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
|
|
trait WithRateLimiting
|
|
{
|
|
protected function clearRateLimiter($method = null, $component = null)
|
|
{
|
|
$method ??= debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, limit: 2)[1]['function'];
|
|
|
|
$component ??= static::class;
|
|
|
|
$key = $this->getRateLimitKey($method, $component);
|
|
|
|
RateLimiter::clear($key);
|
|
}
|
|
|
|
protected function getRateLimitKey($method, $component = null)
|
|
{
|
|
$method ??= debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, limit: 2)[1]['function'];
|
|
|
|
$component ??= static::class;
|
|
|
|
return 'livewire-rate-limiter:'.sha1($component.'|'.$method.'|'.request()->ip());
|
|
}
|
|
|
|
protected function hitRateLimiter($method = null, $decaySeconds = 60, $component = null)
|
|
{
|
|
$method ??= debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, limit: 2)[1]['function'];
|
|
|
|
$component ??= static::class;
|
|
|
|
$key = $this->getRateLimitKey($method, $component);
|
|
|
|
RateLimiter::hit($key, $decaySeconds);
|
|
}
|
|
|
|
protected function rateLimit($maxAttempts, $decaySeconds = 60, $method = null, $component = null)
|
|
{
|
|
$method ??= debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, limit: 2)[1]['function'];
|
|
|
|
$component ??= static::class;
|
|
|
|
$key = $this->getRateLimitKey($method, $component);
|
|
|
|
if (RateLimiter::tooManyAttempts($key, $maxAttempts)) {
|
|
$ip = request()->ip();
|
|
$secondsUntilAvailable = RateLimiter::availableIn($key);
|
|
|
|
throw new TooManyRequestsException($component, $method, $ip, $secondsUntilAvailable);
|
|
}
|
|
|
|
$this->hitRateLimiter($method, $decaySeconds, $component);
|
|
}
|
|
}
|