Ale*_*der 5 authentication passwords model ruby-on-rails bcrypt-ruby
在我的应用中,用户可以编辑他们的个人资料信息 在编辑配置文件表单上,用户可以更改所有字段(名称,标题等).在此同一形式的三个字段:current_password,password,和password_confirmation.我使用bcrypt的has_secure_password功能进行密码验证.我根本不使用Devise.
我希望用户只有在提供了正确的当前密码后才能更改密码.我之前在使用updateUsers控制器的方法中使用了以下代码:
# Check if the user tried changing his/her password and CANNOT be authenticated with the entered current password
if !the_params[:password].blank? && !@user.authenticate(the_params[:current_password])
# Add an error that states the user's current password is incorrect
@user.errors.add(:base, "Current password is incorrect.")
else
# Try to update the user
if @user.update_attributes(the_params)
# Notify the user that his/her profile was updated
flash.now[:success] = "Your changes have been saved"
end
end
Run Code Online (Sandbox Code Playgroud)
但是,此方法的问题在于,如果仅当前密码不正确,则会丢弃对用户模型的所有更改.我想将所有更改保存到用户模型,但如果当前密码不正确,则不更改密码.我试过像这样拆分IF语句:
# Check if the user tried changing his/her password and CANNOT be authenticated with the entered current password
if !the_params[:password].blank? && !@user.authenticate(the_params[:current_password])
# Add an error that states the user's current password is incorrect
@user.errors.add(:base, "Current password is incorrect.")
end
# Try to update the user
if @user.update_attributes(the_params)
# Notify the user that his/her profile was updated
flash.now[:success] = "Your changes have been saved"
end
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为即使当前密码不正确,用户也可以更改他/她的密码.单步执行代码时,虽然"当前密码不正确".@user在运行该update_attributes方法后,错误被添加到它似乎忽略此错误消息.
顺便说一下,该current_password字段是我的User模型中的虚拟属性:
attr_accessor :current_password
Run Code Online (Sandbox Code Playgroud)
我一直试图解决这个问题几个小时,所以我真的可以使用一些帮助.
谢谢!
感谢papirtiger,我得到了这个工作.我从他的回答中改变了一点代码.以下是我的代码.请注意,任何代码段都可以正常工作.
在用户模型中(user.rb)
class User < ActiveRecord::Base
has_secure_password
attr_accessor :current_password
# Validate current password when the user is updated
validate :current_password_is_correct, on: :update
# Check if the inputted current password is correct when the user tries to update his/her password
def current_password_is_correct
# Check if the user tried changing his/her password
if !password.blank?
# Get a reference to the user since the "authenticate" method always returns false when calling on itself (for some reason)
user = User.find_by_id(id)
# Check if the user CANNOT be authenticated with the entered current password
if (user.authenticate(current_password) == false)
# Add an error stating that the current password is incorrect
errors.add(:current_password, "is incorrect.")
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
而我的用户控制器中的代码现在只是:
# Try to update the user
if @user.update_attributes(the_params)
# Notify the user that his/her profile was updated
flash.now[:success] = "Your changes have been saved"
end
Run Code Online (Sandbox Code Playgroud)
您可以在模型级别添加自定义验证,以检查密码是否已更改:
class User < ActiveRecord::Base
has_secure_password
validate :current_password_is_correct,
if: :validate_password?, on: :update
def current_password_is_correct
# For some stupid reason authenticate always returns false when called on self
if User.find(id).authenticate(current_password) == false
errors.add(:current_password, "is incorrect.")
end
end
def validate_password?
!password.blank?
end
attr_accessor :current_password
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2764 次 |
| 最近记录: |