Skip to content

LoginThrottle

A small login/auth throttle on top of symfony/rate-limiter.

Intended for the “count failed authentication attempts per key (IP, username, * …)” pattern: peek before doing expensive auth work, register a failure when auth fails, and reset on success. Backed by any Symfony rate-limiter StorageInterface — use PdoRateLimiterStorage to keep state in the application database (no Redis required). Uses a sliding-window policy. Concurrency: without a LockFactory the window may slightly over/under-count under simultaneous failures, which is harmless for a brute-force throttle; pass a Symfony LockFactory (e.g. backed by a PostgreSqlStore) if you need exactness.

final readonly class LoginThrottle

SourceLoginThrottle.php

public function __construct(StorageInterface $storage, int $maxAttempts = 10, string $interval = '15 minutes', string $id = 'quiote_login', ClockInterface $clock = new SystemClock(…)): mixed

Limiter id namespace (keep distinct per use-case).

ParameterTypeDescription
$storageStorageInterfaceWhere window state is persisted.
$maxAttemptsintAllowed attempts within the interval.
$intervalstringWindow size, e.g. “15 minutes” / “1 hour”.
$idstringLimiter id namespace (keep distinct per use-case).
$clockClockInterface

Returns mixed

MethodDescription
registerFailure(string $key): ?intRegister a single failed attempt for $key.
reset(string $key): voidClear the counter for $key.
retryAfter(string $key): ?intSeconds the caller must wait if $key is currently exhausted, or null if it is still allowed.

public function registerFailure(string $key): ?int

Register a single failed attempt for $key.

Returns the seconds to wait if this failure exceeded the limit (request should be rejected), otherwise null (counted, still within the allowance).

ParameterTypeDescription
$keystring

Returns ?``int

public function reset(string $key): void

Clear the counter for $key.

Call after a successful authentication so a legitimate client is never penalised for earlier typos.

ParameterTypeDescription
$keystring

public function retryAfter(string $key): ?int

Seconds the caller must wait if $key is currently exhausted, or null if it is still allowed.

Does NOT consume an attempt (peek only) — use this at the start of request handling to reject flooding before doing expensive work. Note: a peek (consume(0)) is always “accepted” by the limiter, so we judge exhaustion by remaining tokens rather than isAccepted().

ParameterTypeDescription
$keystring

Returns ?``int