为什么我的password_digest返回“无效哈希”错误?

时间:2012-12-16 23:16:05

标签: ruby-on-rails integration-testing bcrypt

我对运行集成测试以获取用户登录的错误感到有些困惑。以下是跟踪的前几行:

invalid hash
    @ /home/benjamin/.rvm/gems/ruby-1.9.3-p194/gems/bcrypt-ruby-3.0.1/lib/bcrypt.rb:171:in `initialize'
      /home/benjamin/.rvm/gems/ruby-1.9.3-p194/gems/activemodel-3.2.6/lib/active_model/secure_password.rb:58:in `new'
      /home/benjamin/.rvm/gems/ruby-1.9.3-p194/gems/activemodel-3.2.6/lib/active_model/secure_password.rb:58:in `authenticate'
      /home/benjamin/projects/LTClone/app/controllers/sessions_controller.rb:9:in `create'

所以错误来自create行动中的这一行:

if user && user.authenticate(params[:session][:password])

调用authenticate中定义的secure_password.rb方法:

def authenticate(unencrypted_password)
  if BCrypt::Password.new(password_digest) == unencrypted_password
    ...

调用BCrypt::Password.new方法,该方法在bcrypt.rb中定义:

def initialize(raw_hash)
  if valid_hash?(raw_hash)
    ...
  else
    raise Errors::InvalidHash.new("invalid hash")        # line 171
  end
end

因此,由于某种原因,raw_hashvalid_hash?指定的正则表达不匹配,这意味着password_digest变量不是有效的哈希值。基于this answer,我尝试进行身份验证的用户似乎有空白或无效password_digest,但在我在测试中调用create操作之前,我可以puts @user.password_digest,并打印哈希值(Rubular说valid_hash?正则表达式匹配它)。我还将create方法更改为

if user && user.password_digest && user.authenticate(params[:session][:password])

只是为了确保它真的存在。

所以现在我完全难过了。好像我有一个有效的password_digest,但BCrypt::Password.new拒绝承认它。有人知道为什么吗?

3 个答案:

答案 0 :(得分:2)

检查您的用户“password_digest”列。如果它是“nil”那么你会得到这个错误。建议只是删除所有用户并确保正确创建用户。

答案 1 :(得分:1)

我不确定这对你来说是否是同一个解决方案,但我的问题(同样的错误)是通过更改test/fixtures/users.yml文件中存储的灯具中的密码来解决的。一旦我保存并再次运行rails test,测试就通过了。

答案 2 :(得分:0)

您可以使用if / else查看password或password_digest是否为nil

if user.password.nil?
  #redirect back to login with message
else

if user && user.authenticate(params[:session][:password])
  #do your stuff!
end