読者です 読者をやめる 読者になる 読者になる

RailsのsorceryでBrute force対策を行う

認証部分だけですが、ログインロック機能がお手軽に実装できます。
moduleとして組み込んで一部設定変更すればokでした。
Brute force protection · Sorcery/sorcery Wiki

ざっくり

実施方法は、基本githubを見てもらえれば良いです。

rails g sorcery:install brute_force_protection --only-submodules

して、migrateしたのち、以下を設定すれば終了。
 
config/initializers/sorcery.rb

    # -- brute_force_protection --
    # Failed logins attribute name.
    # Default: `:failed_logins_count`
    #
    # user.failed_logins_count_attribute_name =


    # This field indicates whether user is banned and when it will be active again.
    # Default: `:lock_expires_at`
    #
    # user.lock_expires_at_attribute_name =


    # How many failed logins allowed.
    # Default: `50`
    #
    user.consecutive_login_retries_amount_limit = 10


    # How long the user should be banned. in seconds. 0 for permanent.
    # Default: `60 * 60`
    #
    # user.login_lock_time_period =

    # Unlock token attribute name
    # Default: `:unlock_token`
    #
    # user.unlock_token_attribute_name =

    # Unlock token mailer method
    # Default: `:send_unlock_token_email`
    #
    # user.unlock_token_email_method_name =

    # when true sorcery will not automatically
    # send email with unlock token
    # Default: `false`
    #
    # user.unlock_token_mailer_disabled = true

    # Unlock token mailer class
    # Default: `nil`
    #
    # user.unlock_token_mailer = UserMailer

連続10回失敗するとロックが掛かり、1時間で解除されます。

補足

ログイン時にロックされていた場合はメッセージを変えたいところですが 実現するには、用意されている user.locked? メソッドを使うと良さそうです。
注意事項としては、session controller などでloginメソッドを使用していると
思われますが、アカウントロック時は、loginメソッドがnilを返すので
別途キー項目で検索する必要があります。

    if @user = login(params[:session][:email], params[:session][:password])
      redirect_back_or_to(root_url, success: "ログインしました!")
    else
      user = User.find_by_name(params[:session][:email])
      msg = user&.locked? ? "アカウントがロックされました" : "ログイン失敗"
      flash.now[:warning] = msg
      render :new
    end

See Also