如何解决Rails has_secure_password保存成功,但输入nil密码-验证失败
我有一个has_secure_password
和validates :password,presence: true
的用户模型。
然后发生以下情况:
$ rails console
> u = User.create(name: 'user',password: 'password')
=> #<User id: ...
> u.password
=> 'password'
> u.save
=> true
> exit
然后我再次运行控制台,然后。
$ rails console
> u = User.find_by(name: 'user')
=> #<User id: ...
> u.password
=> nil
> u.valid?
=> false
我不明白为什么密码在第一次正确输入后就变为空。
在开发应用程序中也是如此,我可以使用omniauth_google登录用户,并使用SecureRandom.hex(15)
创建密码。当我尝试注销并通过omniauth登录同一用户时,找到了该用户,但user.valid?
给出了一个false
,因为:passowrd神秘地变成了nil
,破坏了登录。>
class User < ApplicationRecord
has_many :notes
has_many :goings
has_many :cafes,through: :goings
has_secure_password
has_secure_password validations: false
validates_uniqueness_of :name,{message: "%{value} name already exist"}
validates :email,presence: { message: "%{attribute} must be given" }
validates :password,presence: {
message: 'You must enter a password'},length: {minimum: 2,message: 'Your password must contain at least 2 characters'
}
validates :name,presence: { message: "%{attribute} must be given" }
def self.from_omniauth(response)
User.find_or_create_by(uid: response[:uid],provider: response[:provider]) do |u|
u.name = response[:info][:name]
u.email = response[:info][:email]
u.password = SecureRandom.hex(15)
end
end
end
解决方法
诀窍在于,对于has_secure_password
,password
并不真正作为持久化模型属性存在。它仅用于处理原始密码以进行加密;之后便是password_digest
(因此,.password
为什么在现有对象上返回nil
。
在验证中“欺骗”自己,仅验证password_digest
(GitHub)的存在和长度:
# This ensures the model has a password by checking whether the password_digest
# is present,so that this works with both new and existing records. However,# when there is an error,the message is added to the password attribute instead
# so that the error message will make sense to the end-user.
validate do |record|
record.errors.add(:password,:blank) unless record.password_digest.present?
end
validates_length_of :password,maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED
当存在要验证的明文密码时,您的自定义验证在初始创建时可以正常工作。但是在那之后,没有一个,因此您的状态检查失败(其他检查无关紧要)。要解决此问题,您可以将on: create
添加到密码验证中,以便仅在新记录的情况下运行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。