Add rate limiter to comment system

This commit is contained in:
2026-01-10 21:04:26 +01:00
parent 819e2fde27
commit e949ba955a
2 changed files with 32 additions and 2 deletions

View File

@@ -8,6 +8,7 @@ use App\Models\User;
use Livewire\Component; use Livewire\Component;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Maize\Markable\Models\Like; use Maize\Markable\Models\Like;
@@ -77,12 +78,24 @@ class Comment extends Component
return; return;
} }
$user = auth()->user();
$rateLimitKey = "send-comment:{$user->id}";
if (RateLimiter::tooManyAttempts($rateLimitKey, 5)) {
$seconds = RateLimiter::availableIn($rateLimitKey);
$this->addError('replyState.body', "Too many comments. Try again in {$seconds} seconds.");
return;
}
RateLimiter::hit($rateLimitKey, 60);
$this->validate([ $this->validate([
'replyState.body' => 'required' 'replyState.body' => 'required'
]); ]);
$reply = $this->comment->children()->make($this->replyState); $reply = $this->comment->children()->make($this->replyState);
$reply->user()->associate(auth()->user()); $reply->user()->associate($user);
$reply->commentable()->associate($this->comment->commentable); $reply->commentable()->associate($this->comment->commentable);
$reply->save(); $reply->save();

View File

@@ -5,6 +5,8 @@ namespace App\Livewire;
use Livewire\Component; use Livewire\Component;
use Livewire\WithPagination; use Livewire\WithPagination;
use Illuminate\Support\Facades\RateLimiter;
class Comments extends Component class Comments extends Component
{ {
use WithPagination; use WithPagination;
@@ -29,8 +31,23 @@ class Comments extends Component
'newCommentState.body' => 'required' 'newCommentState.body' => 'required'
]); ]);
$this->addError('newCommentState.body', "Too many comments. Try again in 1 seconds.");
return;
$user = auth()->user();
$rateLimitKey = "send-comment:{$user->id}";
if (RateLimiter::tooManyAttempts($rateLimitKey, 5)) {
$seconds = RateLimiter::availableIn($rateLimitKey);
$this->addError('newCommentState.body', "Too many comments. Try again in {$seconds} seconds.");
return;
}
RateLimiter::hit($rateLimitKey, 60);
$comment = $this->model->comments()->make($this->newCommentState); $comment = $this->model->comments()->make($this->newCommentState);
$comment->user()->associate(auth()->user()); $comment->user()->associate($user);
$comment->save(); $comment->save();
$this->newCommentState = [ $this->newCommentState = [