Devise with Ruby on Rails-заставить пользователя изменить пароль при первом входе в систему

у меня есть приложение RoR (Rails 4.2, Ruby 2.2.0) под управлением Devise. Я настроил его так, чтобы пользователи-администраторы (идентифицировали логическое значение "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, только: [: edit,: update]" в моем контроллере, он не запускает обновление пароля, и если я помещаю его в пользовательскую модель, я должен поместить процедуру в модель также, а затем он не будет забирать current_user, поскольку он недоступен в модели. Идеально было бы, если бы у Devise был крюк для after_password_edit, подобный крюку after_database_authentication. Мне пришлось переопределить registrations_controller Devise.rb для удаления строки

prepend_before_filter :require_no_authentication, only: [ :cancel]

чтобы пользователи admin могли добавлять новых пользователей. Я попытался разместить update_pass_change там, но он, похоже, не запускает before_save при редактировании пароля.

In прикладные контроллеры.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 - смена пароля при первом входе

2 ответов


вы можете использовать обратный вызов в своей модели и проверить, перед сохранением, если изменения включают атрибут пароля. Что-то вроде этого:--2-->

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 to 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. затем создайте пользовательское действие в ur users_controller для отображения формы изменения пароля и обновления. например. Для отображения формы:custome_password_edit Обновлять : update_user_password также не забудьте написать выше в routes.rb

  4. после успешное изменение стоимости pass_changed to true