需要当前密码才能设置新密码

Posted

技术标签:

【中文标题】需要当前密码才能设置新密码【英文标题】:Require current password to set a new password 【发布时间】:2015-07-23 13:15:27 【问题描述】:

我希望用户在编辑他们的个人资料时输入他们当前的密码。

这是我的用户模型的样子:

attr_accessor :current_password

def current_password
  errors[:current_password] << 'Incorrect password' unless self.current_password == self.password
end

validate :current_password, on: :update

还有我的控制器参数:

def user_params
  params.require(:user).permit(:email, :name, :current_password, :password, :password_confirmation, :phone)
end

和用户表单部分:

<div class="form-group">
  <%= f.label :password, "Current password" %>
  <%= f.password_field :current_password, class: "form-control", placeholder: "Current password" %>
</div>

但我的堆栈级别太深,它进入了验证循环。

我做错了什么?

【问题讨论】:

【参考方案1】:

这个方法

def current_password
  errors[:current_password] << 'Incorrect password' unless self.current_password == self.password
end

调用自身:这就是为什么你得到堆栈太深的错误 - 它陷入了一个无休止地调用自身的循环中。

您尝试做的事情令人困惑,因为current_password 方法正在覆盖attr_accessor :current_password 创建的方法,并且实际上进行了一些验证,而不仅仅是返回值。相反,我会这样做:

attr_accessor :current_password

validate :current_password_same_as_password, on: :update

def current_password_same_as_password
  errors[:current_password] << 'Incorrect password' unless self.current_password == self.password
end

所以,在这里,我将单独留下 attr_accessor 方法:它们是简单的读写到实例变量方法的方法。验证具有不同的方法名称,因此它不会与访问器方法名称发生冲突。

【讨论】:

谢谢,菜鸟的错误。 虽然逻辑不对,在on::update验证上。 self.current_password 期望与用户想要设置的新密码相同,因此它总是会失败。 确实如此 - 如果配置文件编辑包括更改密码,这将不起作用。您需要考虑如何处理。 您可以将新密码放入访问器中,然后使用 before_save 回调将其写入密码字段。【参考方案2】:

current_password 正在调用自己。你有一个无限递归。

你基本上是这样做的:

def current_password
  self.current_password
end

【讨论】:

【参考方案3】:

正如其他答案所说,您在 current_password 中有一个无限循环。我会将验证逻辑提取到它自己的方法中。类似于以下内容。

validate :has_correct_current_password, on: :update

def has_correct_current_password
  errors[:current_password] << 'Incorrect password' unless current_password == password
end

【讨论】:

以上是关于需要当前密码才能设置新密码的主要内容,如果未能解决你的问题,请参考以下文章

如何验证firebase用户当前密码

怎么设置需要账户密码才能解锁?

navicat管理mysql,mysql设置密码之后,navicat使用新密码不能链接空密码却可以

随机密码如何变为固定的?

Active Directory 如何在设置新密码时比较用户以前的密码?

如何以管理方式为忘记密码的 ASP.net 身份用户设置新密码?