Has_secure_password Bcrypt给出nil密码

时间:2017-12-28 03:15:28

标签: ruby-on-rails ruby bcrypt

我正在尝试跟随Michael Hartl的Ruby on Rail书,我在第10章,试图允许用户编辑他们的个人资料设置,这是最奇怪的错误 - 加密' s password_digest正在破坏我的测试。

users.yml里

user:
  name: Example User
  email: example@gmail.com
  password_digest: <%= User.digest("password") %>

当我在rails控制台中运行时,这就是我所看到的

user.valid? =&gt;的

user.errors.full_messages =&GT; [&#34;密码不能为空白&#34;,&#34;密码太短(最少6个字符)&#34;]

user.rb

class User < ApplicationRecord
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
  before_save {
   self.email.downcase!
  }

  validates :name, presence: true, length: { maximum: 50 }
  validates :email, presence: true, length: { maximum: 255 },
            format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
  validates :password, presence: true, length: { minimum: 6 }
  has_secure_password

  # Returns the hash digest of the given string.
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
               BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end
end

我正在使用bcrypt版本&#39; 3.1.11&#39;

我的测试代码

 def setup
    @user = users(:marko)
  end

  test "successful edit" do
    log_in_as(@user)
    get edit_user_path(@user)
    name = "Foo bar"
    email = "foo@bar.com"
    patch user_path(@user), params: { user: {
                                          name: name,
                                          email: email,
                                          password: "password",
                                          password_confirmation: "password" } }
    assert_not flash.empty?
    assert_redirected_to @user
    follow_redirect!
    @user.reload
    assert_equal name, @user.name
    assert_equal email, @user.email
  end

任何想法可能出错?

2 个答案:

答案 0 :(得分:0)

尝试使用以下代码

user:
  name: Example User
  email: example@gmail.com
  password: "password"

Bcrypt在创建新记录时会password attr_accessor进行验证( 可选,同时更新 )。

另外,您应该将allow_blank: true添加到length validation以获取密码,因为当密码本身为空/无

时,不需要长度验证

答案 1 :(得分:0)

有这样一个固定装置:

some_user:
  name: Some user
  email: some_user@example.com
  password_digest: <%= BCrypt::Password.create('secret') %>

将使用该数据直接创建一个用户到数据库中。

然后在验证模型时,您必须实现这样的验证:

validates :password, length: { minimum: 6, allow_blank: true }

请注意,您不应验证 presence

那是因为在表单中,您将要求使用该名称的 password,而不是 password_digest(这是保存到数据库表中的最后一个字段)。

Rails 然后将验证“假”或中间密码字段,如果通过,则生成摘要并将密码字段排除在外。这就是您必须添加 allow_blank: true 的原因,以便测试可以通过。