用Ruby on Rails设计 - 强制用户在第一次登录时更改密码

问题描述:

我有一个运行Devise的RoR应用程序(Rails 4.2,Ruby 2.2.0)。我已经设置了它,以便管理员用户(标识我添加到用户模型中的“is_admin”布尔值)能够创建新的用户帐户,为他们提供生成的密码和确认电子邮件。这一切都正常工作。我还添加了datetime列pass_changed,它应在用户更改其密码时更新,然后针对created_at进行检查,以确保自创建帐户后密码已更改。如果两个日期相等,则用户将被重定向到密码更改表单。用Ruby on Rails设计 - 强制用户在第一次登录时更改密码

我写一个程序来检查用户已经改变了他们的密码,并把它放在我的application_controller.rb:

def check_changed_pass 
@user = current_user 
    if @user.pass_changed == @user.created_at #make sure user has changed their password before accessing internal pages 
    redirect_to edit_user_registration_path, alert: "You must change your password before logging in for the first time" 
    end 
end 

然后在我的internal_controller.rb(用于那些要求用户将所有内部登录:

before_action :check_changed_pass 

到目前为止好,但问题带有尝试更新在正确的时间pass_changed我已经试过各种配置,但我找不到在哪里把这个代码,以便它触发。当密码更新时,但并非每次更新用户模型时都会更新,其中包括每次登录和注销,当我只希望在密码更新时触发它。

如果我在我的控制器中放置“before_save:update_pass_change,只:[:edit,:update]”,它不会触发密码更新,如果我将它放在用户模型中,我必须将程序,然后它将不会拾取current_user,因为它在模型中不可用。理想的情况是,如果Devise具有类似于after_database_authentication挂钩的after_password_edit钩子。我不得不重写设计的registrations_controller.rb删除线

prepend_before_filter :require_no_authentication, only: [ :cancel] 

让管理员用户将能够添加新用户。我试着把update_pass_change放在那里,但它似乎没有在密码编辑时触发before_save。

在application_controller.rb

def update_pass_change # records that the user has changed their password 
    unless current_user.pass_changed != current_user.created_at 
    current_user.pass_changed = Time.now 
    end 
end 

类似的悬而未决的问题:Ruby on Rails: Devise - password change on first login

你可以使用你的模型回调,检查,之前保存,如果改变包括密码属性。事情是这样的:

class User < ActiveRecord::Base 
    before_save :check_password_changed 

    private 
    def check_password_changed 
    self.pass_changed = Time.now if changed.include? 'encrypted_password' 
    end 
end 
+0

我做这个和它的工作不适合一些原因。 check_password_changed运行时没有错误,但不更新pass_changed,尽管密码得到了正确更新。 – 2015-04-08 16:59:28

+1

@HenryD检查'encrypted_pa​​ssword'是否是用户密码的正确属性。 – Doguita 2015-04-08 17:51:18

+0

就是这样!非常感谢这个解决方案完美运作。 – 2015-04-09 12:33:48

您也可以尝试的pass_changed

  1. 变化数据类型来boolean默认值false

  2. 然后在你的application_controller.rb

    before_action :check_pass_changed 
    
    private 
    
    def check_pass_changed 
    unless current_user.pass_changed 
        redirect_to custome_password_edit_path, alert: "You must change your password before logging in for the first time" 
    end 
    end 
    
  3. 然后在您的users_controller中创建自定义操作以显示密码更改表单并进行更新。 例如。 要显示形式:custome_password_edit 更新: update_user_password 也不要忘记在routes.rb

  4. 上面写成功后变化更新的pass_changed价值true