rate limiter
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
module RateLimiter
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
before_action :check_rate_limit, only: [:create]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def check_rate_limit
|
||||||
|
identifier = request.ip
|
||||||
|
cache_key = "rate_limit:#{controller_name}:#{identifier}"
|
||||||
|
|
||||||
|
# Get current attempt count
|
||||||
|
attempts = Rails.cache.read(cache_key) || 0
|
||||||
|
|
||||||
|
if attempts >= max_attempts
|
||||||
|
@rate_limited = true
|
||||||
|
render_rate_limit_error
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# Increment attempt count with expiry
|
||||||
|
Rails.cache.write(cache_key, attempts + 1, expires_in: lockout_period)
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset_rate_limit
|
||||||
|
identifier = request.ip
|
||||||
|
cache_key = "rate_limit:#{controller_name}:#{identifier}"
|
||||||
|
Rails.cache.delete(cache_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_rate_limit_error
|
||||||
|
flash.now[:alert] = "Too many failed attempts. Please try again in #{lockout_period / 60} minutes."
|
||||||
|
render action_name == "create" ? :new : action_name, status: :too_many_requests
|
||||||
|
end
|
||||||
|
|
||||||
|
def max_attempts
|
||||||
|
5
|
||||||
|
end
|
||||||
|
|
||||||
|
def lockout_period
|
||||||
|
15.minutes
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user