使用Ruby on Rails设计 – 强制用户在首次登录时更改密码

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

我写了一个程序来检查用户是否更改了密码并将其放在我的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,only:[:edit,:update]”,它不会在密码更新时触发,如果我将它放在User模型中,我必须将该过程放在模型中同样,然后它不会拾取current_user,因为它在模型中不可用。 理想的是,如果Devise有一个类似于after_database_authentication挂钩的after_password_edit挂钩。 我不得不重写Devise的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:设计 – 首次登录时更改密码

您可以在模型上使用回调,并在保存之前检查更改是否包含您的密码属性。 像这样的东西:

 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 

你也可以试试这个

  1. pass_changed数据类型pass_changedboolean ,默认值为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. 然后在ur users_controller中创建自定义操作以显示密码更改表单并进行更新。 例如。 要显示表单: custome_password_edit更新: update_user_password也不要忘记在routes.rb上面写

  4. 成功更改后,将pass_changed的值更新为true