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 的作品非常好!

我遇到的一些小问题如下:

  1. 如果你有 uninitialized constant Devise::Extends (NameError)(可能只是因为旧的 ruby 版本?)那么你可以只使用嵌套模块定义。
  2. 如果您需要允许对未经过身份验证的用户执行某些操作 运行,那么您可以跳过过滤器。

下面是更新的代码段。

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