" BCrypt ::错误:: InvalidHash"试图登录时 [英] "BCrypt::Errors::InvalidHash" when trying to sign in

查看:906
本文介绍了" BCrypt ::错误:: InvalidHash"试图登录时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图完成一个项目。我正在使用用户模型。
当我注册时,一切似乎都没问题。但是,当我尝试登录同一个成员时,我收到此错误。



很抱歉,但出错了。
heroku logs 文件显示错误为:

  BCrypt :: Errors :: InvalidHash(无效散列):
app / controllers / sessions_controller.rb:8:在`create'

my * sessions_controller * 为:

  class SessionsController< ApplicationController 

def new
end

def create
user = User.find_by_email(params [:session] [:email])
如果用户&& user.authenticate(params [:session] [:password])
sign_in user
redirect_to user
else
flash.now [:error] ='无效的电子邮件/密码组合'
渲染'新'
结束
结束


def破坏
sign_out
redirect_to root_path
结束
end

用户模型为:

  class User< ActiveRecord :: Base 
attr_accessible:email,:name,:nickname,:password,:password_confirmation
has_secure_password

$ b before_save {| user | user.email = email.downcase}
before_save {| user | user.nickname = nickname.downcase}
before_save:create_remember_token
....验证......

私人

def create_remember_token
self.remember_token = SecureRandom.urlsafe_base64
结束
结束

是我的 session.helper

 模块SessionsHelper 

def sign_in(user )
cookies.permanent [:remember_token] = user.remember_token
self.current_user = user
end
def signed_in?
!current_user.nil?
end

def current_user =(user)
@current_user = user
end
$ b def current_user
@current_user || = User.find_by_remember_token(cookies [:remember_token])
结束

def sign_out
self.current_user =零
cookies.delete(:remember_token)
结束
结束

我试过了heroku rake db:migrate,heroku restart ..没有更改。

解决方案

BCrypt散列(包括如果该字段为空)。

基于注释,它看起来像您刚才创建的用户 has_secure_password 不在那里,所以密码摘要永远不会被存储。查看数据库,您可能会发现该用户的 password_digest 为空。



尽管在评论中讨论了,但我做了一个(不正确的)猜测关于为什么密码是错误的,我已经写了解释。所以在这里,任何未来的访问者都会遇到这个问题,即使它不直接适用于此:




这通常发生在从使用SHA1或其他算法切换到BCrypt但无法重新散列BCrypt中的密码时。由于您无法访问原始密码(或者至少不应该......),因此您必须使用 BCrypt和原始身份验证方案,因此切换有点难看。例如,如果您之前使用SHA1并且现在使用BCrypt,则必须将SHA1密码哈希视为 BCrypt输入的纯文本密码。例如,你可以像这样创建一个BCrypt摘要:

  sha1_password = Digest :: SHA1.hexdigest(#{salt} #{real_password})
self.password_digest = BCrypt :: Password.create(sha1_password).to_s

然后,您可以根据 访问的sha1密码哈希创建bcrypt password_digests。



您可以像这:

  sha1_password = Digest :: SHA1.hexdigest(#{salt}#{attempted_pa​​ssword})
BCrypt :: Password.new(self.password_digest)== sha1_password

我在上面的例子中使用了SHA1 ,但这也适用于其他散列算法。


I am trying to finish a project. I am working with user models. When I signup everything seems ok . But when I try to signin the same member I get this error.

We're sorry, but something went wrong. heroku logs file shows error as:

BCrypt::Errors::InvalidHash (invalid hash):
  app/controllers/sessions_controller.rb:8:in `create'

my *sessions_controller* is :

class SessionsController < ApplicationController

  def new
  end

   def create
    user = User.find_by_email(params[:session][:email])
    if user && user.authenticate(params[:session][:password])
      sign_in user
      redirect_to user
    else
      flash.now[:error] = 'Invalid email/password combination'
      render 'new'
    end
  end


  def destroy
    sign_out
    redirect_to root_path
  end
end

and user model is :

class User < ActiveRecord::Base
  attr_accessible :email, :name, :nickname,:password, :password_confirmation 
  has_secure_password


  before_save { |user| user.email = email.downcase }
  before_save { |user| user.nickname = nickname.downcase }
  before_save :create_remember_token
....validations......

    private

    def create_remember_token
      self.remember_token = SecureRandom.urlsafe_base64
    end
end 

this is my session.helper

module SessionsHelper

  def sign_in(user)
    cookies.permanent[:remember_token] = user.remember_token
    self.current_user = user
  end
  def signed_in?
    !current_user.nil?
  end

  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user ||= User.find_by_remember_token(cookies[:remember_token])
  end

  def sign_out
    self.current_user = nil
    cookies.delete(:remember_token)
  end
end

I tried heroku rake db:migrate, heroku restart.. there is no change.

解决方案

This means that the hash stored in password_digest is not a valid BCrypt hash (including if the field is empty).

Based on the comments, it looks like you just created the user at a time the has_secure_password wasn't there, so the password digest never got stored. Look in the database, you'll probably see that password_digest is empty for that user. Remove the user from the database and re-create with your new working code and it should work.

While discussing with in the comments though, I made an (incorrect) guess about why the passwords would be wrong, and I already wrote up the explanation. So here it is for any future visitor that does have this problem, even though it doesn't apply directly here:


This typically happens when you switch from using SHA1 or another algorithm to BCrypt but fail to re-hash the passwords in BCrypt. Since you don't have access to the original passwords (or at least you shouldn't...), it's a bit ugly to switch because you have to use both BCrypt and the original authentication scheme. For example, if you were using SHA1 before and now use BCrypt, you have to treat the SHA1 password hash as the plain text password for BCrypt input. For example, you might create a BCrypt digest like this:

sha1_password = Digest::SHA1.hexdigest("#{salt}#{real_password}")
self.password_digest = BCrypt::Password.create(sha1_password).to_s

Then, you can create bcrypt password_digests based on the sha1 password hashes that you do have access to.

You would authenticate like this:

sha1_password = Digest::SHA1.hexdigest("#{salt}#{attempted_password}")
BCrypt::Password.new(self.password_digest) == sha1_password

I used SHA1 in the above examples, but this will work for other hashing algorithms as well.

这篇关于&QUOT; BCrypt ::错误:: InvalidHash&QUOT;试图登录时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆