【问题标题】:Custom message on devise lockable n-th attempt关于设计可锁定第 n 次尝试的自定义消息
【发布时间】:2017-05-16 14:27:09
【问题描述】:
【问题讨论】:
标签:
ruby-on-rails
ruby
devise
【解决方案1】:
你可以用
覆盖设计代码
module Devise::Models::Lockable
def unauthenticated_message
# If set to paranoid mode, do not show the locked message because it
# leaks the existence of an account.
if Devise.paranoid
super
elsif access_locked? || (lock_strategy_enabled?(:failed_attempts) && attempts_exceeded?)
:locked
elsif lock_strategy_enabled?(:failed_attempts) && last_attempt? && self.class.last_attempt_warning
:last_attempt
else
return "invalid_fail_attempt_#{failed_attempts}" if temporary
#super normally this would return :invalid see super class
end
end
end
那么你需要添加你的翻译
devise.failure.user.invalid_1: "one shot down! 4 to go"
devise.failure.user.invalid_2: "ooh 2 strikes!!"
devise.failure.user.invalid_3: "3 strikes!! but your not out yet! 2 left"
您不需要数字 4,因为它将由在 last_attempt? 上运行的块处理(假设您有 5 次尝试限制,请根据需要进行调整。)
该代码也可能放在超类中的任何位置..
【解决方案2】:
这个想法很有趣,但行不通,因为lockable 在create 之前被调用,所以我创建了一个自定义操作,我在create 之前调用它。
这对我有用:
class User::SessionsController < Devise::SessionsController
before_action :check_failed_attempts, only: :create
def after_sign_in_path_for(user)
# some code
end
def create
super
# create some stuff and check others
end
def destroy
# may be destroy and deal with cookies
super
end
def check_failed_attempts
flash.clear
email = self.params["user"]["email"]
return unless email
user = User.find_by_email(email)
return unless user
failed_attempts = user.failed_attempts
maximum_attempts = User.maximum_attempts
attempts_left = maximum_attempts - failed_attempts - 1
if attempts_left != maximum_attempts and attempts_left > 1
flash[:notice] = I18n.t 'devise.failure.n_attempt', attempts_left: attempts_left
end
end
end
【解决方案3】:
也许是一个自定义的 SessionsController,我猜这个设计使用了动态方法,我找不到 :last_attempt 被调用的位置来覆盖 unauthenticated_message 方法
def create
if self.resource.failed_attempts != self.resource.class.maximum_attempts - 1 and self.resource.failed_attempts != 0
attempts_left = self.resource.failed_attempts
flash[:alert] = I18n.t 'some_path.errors.attempts', attempts_left: attempts_left
super
end
这个想法是在您有 1 次或少于最大尝试次数时添加一个闪光警报,在最大尝试次数和最后一次尝试次数的情况下,您将收到默认消息