简体   繁体   English

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

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

I have a RoR application (Rails 4.2, Ruby 2.2.0) running Devise. 我有一个运行Devise的RoR应用程序(Rails 4.2,Ruby 2.2.0)。 I have set it up so that admin users (identified the "is_admin" boolean I added to the user model) are able to create new user account, provide them with a generated password and confirmation email. 我已将其设置为管理员用户(标识为我添加到用户模型的“is_admin”布尔值)能够创建新用户帐户,为他们提供生成的密码和确认电子邮件。 This is all working properly. 这一切都正常。 I have also added the datetime column pass_changed which should be updated when a user changes their password, and then checked against created_at to make sure that the password has changed since the account was created. 我还添加了datetime列pass_changed,应在用户更改密码时更新,然后检查created_at以确保自创建帐户后密码已更改。 If the two dates are equal then the user is redirected to the password change form. 如果两个日期相等,则将用户重定向到密码更改表单。

I wrote a procedure for checking that the user has changed their password and placed it in my application_controller.rb: 我写了一个程序来检查用户是否更改了密码并将其放在我的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

Then in my internal_controller.rb (used for all internal that require the user to be logged in: 然后在我的internal_controller.rb中(用于需要用户登录的所有内部:

before_action :check_changed_pass

So far so good, but the problem comes with attempting to update pass_changed at the right time. 到目前为止一切顺利,但问题在于尝试在正确的时间更新pass_changed。 I have tried various configurations, but I can't find where to put this code so that it triggers when a password is updated, but not every time the user model is updated, which includes every login and logout, when I only want it to trigger if the password gets updated. 我尝试了各种配置,但我找不到放置此代码的位置,以便在更新密码时触发,但不是每次更新用户模型时都会触发,包括每次登录和注销,当我只想要它时如果密码更新,则触发。

If I place "before_save :update_pass_change, only: [:edit, :update]" in my controller it doesn't trigger on a password update, and if I place it in the User model, I have to put the procedure in the model as well and then it won't pick up current_user as its not available in the model. 如果我在我的控制器中放置“before_save:update_pass_change,only:[:edit,:update]”,它不会在密码更新时触发,如果我将它放在User模型中,我必须将该过程放在模型中同样,然后它不会获取current_user,因为它在模型中不可用。 The ideal thing would be if Devise had a hook for after_password_edit similar to the after_database_authentication hook. 理想的是,如果Devise有一个类似于after_database_authentication挂钩的after_password_edit挂钩。 I had to override Devise's registrations_controller.rb to remove the line 我不得不重写Devise的registrations_controller.rb来删除该行

prepend_before_filter :require_no_authentication, only: [ :cancel]

So that admin users would be able to add new users. 这样管理员用户就可以添加新用户了。 I tried placing update_pass_change there, but it doesn't seem to trigger before_save on a password edit. 我尝试在那里放置update_pass_change,但它似乎没有在密码编辑时触发before_save。

In application_controller.rb 在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

Similar unanswered question: Ruby on Rails: Devise - password change on first login 类似的未回答的问题: Ruby on Rails:Devise - 首次登录时更改密码

You could use a callback on your model and check, before save, if the changes includes your password attribute. 您可以在模型上使用回调,并在保存之前检查更改是否包含您的密码属性。 Something like this: 像这样的东西:

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

You can also try this 你也可以试试这个

  1. change datatype of pass_changed to boolean with default value false pass_changed数据类型pass_changedboolean ,默认值为false

  2. Then in your application_controller.rb 然后在你的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. Then Create custom action in ur users_controller to display the password change form and to update. 然后在ur users_controller中创建自定义操作以显示密码更改表单并进行更新。 eg. 例如。 To display form : custome_password_edit To update : update_user_password also dont forget to write above in routes.rb 要显示表单: custome_password_edit更新: update_user_password也不要忘记在routes.rb上面写

  4. after successful change update the value of pass_changed to true 成功更改后,将pass_changed的值更新为true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM