Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: "BCrypt::Errors::InvalidHash" when trying to sign in

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.

like image 658
ytsejam Avatar asked Jun 14 '12 16:06

ytsejam


2 Answers

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.

like image 179
Ben Lee Avatar answered Sep 22 '22 16:09

Ben Lee


An update to the BCrypt gem fixed this issue for me

like image 45
Ashley Avatar answered Sep 19 '22 16:09

Ashley