在 Rails 上设计 Ruby - 强制用户在首次登录时更改密码

Devise with Ruby on Rails - Force user to change password on first login

我有一个 RoR 应用程序(Rails 4.2,Ruby 2.2.0)运行 设计。我已对其进行设置,以便管理员用户(标识我添加到用户模型的 "is_admin" 布尔值)能够创建新的用户帐户,向他们提供生成的密码和确认电子邮件。这一切都正常工作。我还添加了日期时间列 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]" 放在我的控制器中,它不会触发密码更新,如果我将它放在用户模型中,我必须将过程也放在模型中,然后它不会选择 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: 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

你也可以试试这个

  1. pass_changed 的数据类型更改为 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. 上面写
  5. 成功更改后将 pass_changed 的值更新为 true