【问题标题】:Rails devise disable password recovery for certain user typesRails 为某些用户类型设计禁用密码恢复
【发布时间】:2015-05-10 12:14:25
【问题描述】:

在我的 Rails 项目中,我有不同类型的用户,其中一种拥有 user_status :admin,与其他用户不同,它拥有编辑内容的完全权限。出于显而易见的原因,我想为这些类型的用户添加额外的安全性,特别是完全禁用密码恢复。

什么是覆盖标准设计密码恢复(:recoverable设计模块)方法的正确方法,以便当用户尝试为管理员用户(user_status == "admin")的用户获取重置密码链接时,系统会给出返回“未找到标准电子邮件”消息?

这有点像未回答的问题:Restrict Devise password recovery to only certain users

提前谢谢你。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 authentication devise


    【解决方案1】:

    未测试,但我认为您可以覆盖 User 模型中的reset_password!,如下所示:

    def reset_password!(new_password, new_password_confirmation)
      return false if user_status == 'admin'
      super
    end
    

    如果用户是管理员,这将防止密码被重置。

    我不知道这是否是最好的覆盖方法,在您的用户模型中还有更多设计可恢复的方法可以被覆盖,即send_reset_password_instructions。查看manual 了解所有有趣的方法。

    【讨论】:

      【解决方案2】:

      我选择并且对我有用的方法是通过将以下内容添加到 models/user.rb 来覆盖 User 模型的 send_reset_password_instructions 方法:

      def send_reset_password_instructions
        return false if self.user_status == 'admin'
        super
      end
      

      这使得 Devise 不会在电子邮件属于管理员帐户的情况下执行任何操作。

      【讨论】:

      • 我使用的是 rails 6,只有 return false 不适合我。我添加了errors.add(:user_status,"can't reset the password for admin"),然后一切正常
      【解决方案3】:

      对于任何未来的观众,这是另一种方法。 Vitaly 的示例确实对我有用,但我仍然收到“您的密码电子邮件已发送”。注意(我想要一个单独的警报来闪烁),所以我走了另一条路。

      扩展 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' }
      

      这会将您的应用定向到扩展控制器,然后如果您的条件不满足,则点击设计控制器(“超级”)。

      【讨论】:

        【解决方案4】:

        来自 Keller Martin 的Snippet above 效果很好!

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

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

        下面是更新的sn-p。

        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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-04-27
          • 2014-10-01
          • 2023-03-10
          • 2011-08-25
          • 2013-01-03
          • 2012-02-01
          • 2012-01-22
          • 2014-01-17
          相关资源
          最近更新 更多