Rails 为某些用户类型设计禁用密码恢复
Rails devise disable password recovery for certain user types
在我的 Rails 项目中,我有不同类型的用户,其中一位拥有 user_status :admin
,与其他用户不同,他们拥有编辑内容的全部权利。出于明显的原因,我想为这些类型的用户增加额外的安全性,特别是完全禁用密码恢复。
覆盖标准 Devise 密码恢复(:recoverable
Devise 模块)方法的正确方法是什么,以便当用户尝试为管理员用户获取重置密码时 link (user_status == "admin"
)系统返回"standard email not found"信息?
这有点像未回答的问题:Restrict Devise password recovery to only certain users
提前致谢。
未测试,但我认为您可以按如下方式覆盖用户模型中的 reset_password!
:
def reset_password!(new_password, new_password_confirmation)
return false if user_status == 'admin'
super
end
如果用户是管理员,这可以防止密码被重置。
我不知道这是否是最好的覆盖方法,在您的用户模型中有更多设计可恢复的方法可供覆盖,即 send_reset_password_instructions
。检查 manual 所有有趣的方法。
我选择的对我有用的方法是通过将以下内容添加到 models/user.rb
来覆盖用户模型的 send_reset_password_instructions
方法:
def send_reset_password_instructions
return false if self.user_status == 'admin'
super
end
这使得 Devise 在电子邮件属于管理员帐户的情况下不会执行任何操作。
对于任何未来的观众,这是另一种方法。 Vitaly 的示例确实对我有用,但我仍然收到 "Your password email has been sent." 通知(我想要一个单独的警报来闪烁),所以我走了另一条路。
扩展 Devise::PasswordsController 对我来说是最简单的解决方案:
class Devise::Extends::PasswordsController < Devise::PasswordsController
def create
if some_condition?
redirect_to :root
flash[:alert] = 'You cannot reset your password, buddy.'
else
super
end
end
然后,在routes.rb:
devise_for :users, controllers: { passwords: 'devise/extends/passwords' }
这会将您的应用定向到扩展控制器,如果不满足您的条件,则点击设计控制器 ("super")。
来自 Keller Martin 的作品非常好!
我遇到的一些小问题如下:
- 如果你有
uninitialized constant Devise::Extends (NameError)
(可能只是因为旧的 ruby 版本?)那么你可以只使用嵌套模块定义。
- 如果您需要允许对未经过身份验证的用户执行某些操作 运行,那么您可以跳过过滤器。
下面是更新的代码段。
module Devise
module Extends
class PasswordsController < Devise::PasswordsController
skip_before_filter :authenticate_user!, :only => [ :edit ]
def edit
redirect_to "https://www.google.com/"
end
end
end
end
在我的 Rails 项目中,我有不同类型的用户,其中一位拥有 user_status :admin
,与其他用户不同,他们拥有编辑内容的全部权利。出于明显的原因,我想为这些类型的用户增加额外的安全性,特别是完全禁用密码恢复。
覆盖标准 Devise 密码恢复(:recoverable
Devise 模块)方法的正确方法是什么,以便当用户尝试为管理员用户获取重置密码时 link (user_status == "admin"
)系统返回"standard email not found"信息?
这有点像未回答的问题:Restrict Devise password recovery to only certain users
提前致谢。
未测试,但我认为您可以按如下方式覆盖用户模型中的 reset_password!
:
def reset_password!(new_password, new_password_confirmation)
return false if user_status == 'admin'
super
end
如果用户是管理员,这可以防止密码被重置。
我不知道这是否是最好的覆盖方法,在您的用户模型中有更多设计可恢复的方法可供覆盖,即 send_reset_password_instructions
。检查 manual 所有有趣的方法。
我选择的对我有用的方法是通过将以下内容添加到 models/user.rb
来覆盖用户模型的 send_reset_password_instructions
方法:
def send_reset_password_instructions
return false if self.user_status == 'admin'
super
end
这使得 Devise 在电子邮件属于管理员帐户的情况下不会执行任何操作。
对于任何未来的观众,这是另一种方法。 Vitaly 的示例确实对我有用,但我仍然收到 "Your password email has been sent." 通知(我想要一个单独的警报来闪烁),所以我走了另一条路。
扩展 Devise::PasswordsController 对我来说是最简单的解决方案:
class Devise::Extends::PasswordsController < Devise::PasswordsController
def create
if some_condition?
redirect_to :root
flash[:alert] = 'You cannot reset your password, buddy.'
else
super
end
end
然后,在routes.rb:
devise_for :users, controllers: { passwords: 'devise/extends/passwords' }
这会将您的应用定向到扩展控制器,如果不满足您的条件,则点击设计控制器 ("super")。
我遇到的一些小问题如下:
- 如果你有
uninitialized constant Devise::Extends (NameError)
(可能只是因为旧的 ruby 版本?)那么你可以只使用嵌套模块定义。 - 如果您需要允许对未经过身份验证的用户执行某些操作 运行,那么您可以跳过过滤器。
下面是更新的代码段。
module Devise
module Extends
class PasswordsController < Devise::PasswordsController
skip_before_filter :authenticate_user!, :only => [ :edit ]
def edit
redirect_to "https://www.google.com/"
end
end
end
end