Ruby on rails 为什么添加密码恢复后密码验证不起作用?
面对一个我不清楚的问题。 我在注册时使用了密码验证Ruby on rails 为什么添加密码恢复后密码验证不起作用?,ruby-on-rails,ruby,authentication,password-encryption,actioncontroller,Ruby On Rails,Ruby,Authentication,Password Encryption,Actioncontroller,面对一个我不清楚的问题。 我在注册时使用了密码验证 def pass\u val 如果密码摘要计数(“a-z”)错误出现在发送密码重置方法中。 向这个方法添加了(:validate=>false),它成功了 def发送\密码\重置 确认令牌 self.password\u reset\u sent\u at=Time.zone.now 拯救(:validate=>false) AuthorMailer.password\u重置(self.deliver)! 结束 在vallidation中,我
def pass\u val
如果密码摘要计数(“a-z”)错误出现在发送密码重置方法中。
向这个方法添加了(:validate=>false)
,它成功了
def发送\密码\重置
确认令牌
self.password\u reset\u sent\u at=Time.zone.now
拯救(:validate=>false)
AuthorMailer.password\u重置(self.deliver)!
结束
在vallidation中,我使用密码
似乎您自己已经找到了解决方案。但是,我不确定您是否理解发生这种情况的原因
让我们从一个重要的事实开始:password\u digest
不包含密码,而是密码的哈希版本。(哈希函数的结果也称为摘要。)您需要将验证添加到password
属性,因为该属性包含实际密码
将新密码分配给作者时,密码和密码摘要都将被分配一个新值。您可以想象密码设置器的外观如下:
def password=(password)
@password = password
@password_digest = do_some_hash_magic(password)
end
因为密码
是在您将其分配给作者时设置的,所以您可以验证其内容
要知道的另一件重要事情是,实际密码永远不会保存到数据库中,只有密码摘要(出于安全原因)会保存到数据库中。因此,当您(重新)从数据库加载实例时,密码
设置为零
,因为应用程序不再知道它是什么
与使用save(validate:false)
跳过验证不同,我建议使用该选项或使仅当密码
不是nil
时才触发验证
validates :password, length: { in: 8..255 }, allow_nil: true
validates :password, format: { with: /\p{Lower}/, message: :no_lower }, allow_nil: true
validates :password, format: { with: /\p{Upper}/, message: :no_upper }, allow_nil: true
validates :password, format: { with: /\p{Digit}/, message: :no_digit }, allow_nil: true
validates :password, format: { with: /[\p{S}\p{P}]/, message: :no_special }, allow_nil: true
或者,您可以更显式地使用带有自定义上下文的选项,仅在希望验证满足以下条件时触发验证:
validates :password, length: { in: 8..255 }, on: :password
validates :password, format: { with: /\p{Lower}/, message: :no_lower }, on: :password
validates :password, format: { with: /\p{Upper}/, message: :no_upper }, on: :password
validates :password, format: { with: /\p{Digit}/, message: :no_digit }, on: :password
validates :password, format: { with: /[\p{S}\p{P}]/, message: :no_special }, on: :password
上下文不必以属性命名,使用:foo
而不是:password
也可以。然后,您可以在调用valid?
或save
时通过传递上下文来运行这些验证
author.valid?(:password)
author.save(context: :password)
如果您使用Rails 5或更高版本,如果您希望混合运行验证,那么可以将多个上下文作为一个数组传递<代码>作者.有效?([:创建,:密码])
有关所用正则表达式的更多信息,请查看。密码摘要
不是密码,因此您不应该对其进行任何内容检查。发送密码重置
做什么?显示代码。我猜它发送一封带有链接的电子邮件,当用户点击链接时会发生什么?显示代码,我猜它显示了一个表单,当用户提交表单时会发生什么?显示代码
author.valid?(:password)
author.save(context: :password)