如何覆盖设计安全扩展PasswordExpiredController

时间:2016-12-02 11:20:49

标签: ruby-on-rails devise

我想覆盖show logic,以便不仅在过期时允许更改密码,而且在几天前更新密码。我需要修改或替换此before_filter logic

def skip_password_change
    return if !resource.nil? && resource.need_change_password?
    redirect_to :root
end

我想让我的控制器像这样:

class PasswordsController < Devise::PasswordExpiredController
    # ...
    def skip_password_change
        return if !resource.nil? && (resource.need_change_password? || ... )
        redirect_to :root
    end
end

如何实现我的目标?

UPD: 下面的所有答案都是正确的,我错过了一件事 - 我的自定义控制器被放置在controllers / admin目录中,所以我应该将其命名为Admin :: CustomPasswordExpiredController,但我错过了命名空间前缀Admin和rails陷入循环依赖。

3 个答案:

答案 0 :(得分:1)

您可以尝试此解决方法,首先跳过before_action方法的默认skip_password_change,然后添加自定义方法以将其包装在条件中。试试这个

class PasswordsController < Devise::PasswordExpiredController
  skip_before_action :skip_password_change, only: :show
  before_action :skip_password_change_show, only: :show

  def skip_password_change_show
    return if !resource.nil? && (resource.need_change_password? || #yourcondition )
    redirect_to :root
  end
end

希望有所帮助!

答案 1 :(得分:1)

转到路线文件并覆盖那里的控制器方法。

类似devise_for :users, controllers: {x: 'y'}的内容,其中x是您想要覆盖的设备的控制器名称,y是您要用

覆盖的自定义控制器的名称

答案 2 :(得分:1)

只需使用自定义控制器扩展设计控制器:

# config/routes.rb
devise_for :users, controllers: { passwords: 'custom_passwords' }

# app/controllers/custom_passwords_controller.rb
class CustomPasswordsController < Devise::PasswordsController
  def edit
    resource = resource_class.new
    return unless resource.need_change_password? # your middleware logic here
    super
  end
end

更多设施可以在设计PasswordsController documentation中找到(点击&#34;查看来源&#34;)