在我的应用中,用户可以编辑他们的个人资料信息。在编辑配置文件表单上,用户可以更改所有字段(姓名、职务等)。在同一个表单上有三个字段:current_password
, password
, 和 password_confirmation
.我正在使用 bcrypt
的 has_secure_password
密码认证功能。我根本不使用设计。
我希望用户只有在提供了正确的当前密码后才能更改他们的密码。我之前在 update
中使用以下代码完成了这项工作我的用户 Controller 的方法:
# 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
然而,这种方法的问题在于,如果当前密码不正确,它会丢弃对用户模型的所有更改。如果当前密码不正确,我想保存对用户模型的所有更改,但不保存密码更改。我试过像这样拆分 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
这不起作用,因为即使当前密码不正确,用户也可以更改他/她的密码。单步执行代码时,尽管“当前密码不正确”。错误已添加到
@user
,经过 update_attributes
方法,它似乎忽略了这个错误信息。顺便说一句,
current_password
字段是我的用户模型中的虚拟属性:attr_accessor :current_password
我一直在努力解决这个问题几个小时,所以我真的可以使用一些帮助。
谢谢!
解决方案
感谢 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
我的用户 Controller 中的代码现在很简单:
# 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
最佳答案
您可以在模型级别添加自定义验证,以检查密码是否已更改:
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
关于ruby-on-rails - Rails 4 - 仅当当前密码正确时才允许更改密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30293379/