danharrin/livewire-rate-limiting
Add rate limiting to Laravel Livewire actions to stop spam and brute-force clicks. Configure limits per component or method, with customizable keys, decay times, and responses when limits are exceeded—simple protection that feels native to Livewire.
RateLimited or use the withRateLimiting() helper. No need to modify existing Livewire components unless custom logic is needed.RateLimiter facade, but Livewire-specific edge cases (e.g., concurrent requests) may need integration tests.throttle or debounce on client-side triggers.HandleLivewire middleware.Cache::tags()).TooManyRequestsException by default—does the UI need a graceful degradation (e.g., queueing or retry logic)?Log::channel() or a custom event listener.wire:ignore.self.Illuminate/RateLimiting) ensures consistency with existing auth, caching, and queue layers.throttle middleware) for SPAs.submitForm, deleteItem).withRateLimiting() helper for quick wins:
public function submitForm()
{
return withRateLimiting('submit-form', fn () => [
'maxAttempts' => 5,
'decaySeconds' => 10,
]);
}
RateLimiter facade.composer.json or fork if needed.wire:method vs. wire:click).redis-cli --stat).TooManyRequestsException (e.g., show a retry button).// Alpine.js
<button @click.debounce="submitForm(500)">Submit</button>
config/rate-limiting.php or a dedicated service provider to avoid scattered logic.wire:model.live or wire:submit changes.Artisan::call('cache:clear') cautiously—may reset rate-limit counters.RateLimiter::tooManyAttempts(function () {
Log::warning('Rate limit exceeded', ['key' => $key]);
});
RateLimiter::extend('custom', function ($request) {
return Limit::perMinute(5)->response(function () {
return response()->json(['error' => 'Too many submissions. Try again later.'], 429);
});
});
slowlog and consider pipelining.user:{id}:action:{name}).| Failure Scenario | Impact | Mitigation |
|---|---|---|
| Redis cache failure | All rate-limiting disabled | Fallback to database-based tracking or disable limits gracefully. |
| Livewire action race conditions | False rate-limit triggers | Use sync for critical actions or implement client-side throttling. |
| Cache key collisions | Incorrect rate-limiting | Design keys to be unique (e.g., include user ID + action name). |
| Package version incompatibility | Broken Livewire actions | Pin package version in composer.json and test upgrades. |
| DDoS via rate-limit exhaustion | Cache saturation | Implement IP-based rate-limiting at the load balancer (e.g., Nginx limit_req). |
README.md or Swagger/OpenAPI specs.delete actions").artisan livewire:test with rate-limit assertions).How can I help you explore Laravel packages today?