web-dev-qa-db-fra.com

"BCrypt :: Errors :: InvalidHash" lors de la tentative de connexion

J'essaie de terminer un projet. Je travaille avec des modèles utilisateurs. Lorsque je m'inscris, tout semble correct. Mais lorsque j'essaye de me connecter au même membre, j'obtiens cette erreur.

Nous sommes désolés, une erreur s'est produite. Le fichier journaux Heroku affiche une erreur comme:

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

mon * sessions_controller * est:

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

et modèle utilisateur est:

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 

c'est mon 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

J'ai essayé heroku rake db: migrer, heroku redémarrer .. il n'y a pas de changement.

43
ytsejam

Cela signifie que le hachage stocké dans password_digest n'est pas un hachage BCrypt valide (y compris si le champ est vide).

Sur la base des commentaires, il semble que vous venez de créer l'utilisateur à la fois has_secure_password n'était pas là, donc le résumé du mot de passe n'a jamais été stocké. Regardez dans la base de données, vous verrez probablement que password_digest est vide pour cet utilisateur. Supprimez l'utilisateur de la base de données et recréez avec votre nouveau code de travail et cela devrait fonctionner.

Cependant, en discutant avec dans les commentaires, j'ai fait une supposition (incorrecte) sur la raison pour laquelle les mots de passe seraient incorrects, et j'ai déjà rédigé l'explication. Donc, ici, c'est pour tout futur visiteur qui a ce problème, même s'il ne s'applique pas directement ici:


Cela se produit généralement lorsque vous passez de l'utilisation de SHA1 ou d'un autre algorithme à BCrypt mais que vous ne ré-hachez pas les mots de passe dans BCrypt. Puisque vous n'avez pas accès aux mots de passe d'origine (ou du moins vous ne devriez pas ...), il est un peu moche de changer car vous devez utiliser les deux BCrypt et le schéma d'authentification d'origine. Par exemple, si vous utilisiez SHA1 avant et utilisez maintenant BCrypt, vous devez traiter le hachage du mot de passe SHA1 as le mot de passe en texte brut pour l'entrée BCrypt. Par exemple, vous pouvez créer un résumé BCrypt comme ceci:

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

Ensuite, vous pouvez créer bcrypt password_digests en fonction des hachages de mot de passe sha1 auxquels vous faites avez accès.

Vous vous authentifieriez comme ceci:

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

J'ai utilisé SHA1 dans les exemples ci-dessus, mais cela fonctionnera également pour d'autres algorithmes de hachage.

79
Ben Lee

J'avais déjà des utilisateurs en direct et, de même, j'avais déjà enregistré des mots de passe non chiffrés dans la base de données. Une fois que j'ai commencé à utiliser bcrypt, il s'attendait à un mot de passe crypté, et quand il ne l'a pas trouvé, il a produit cette erreur.

Par conséquent, j'ai ajouté ce sauvetage pour détecter l'erreur et inviter les utilisateurs hérités à réinitialiser leur mot de passe:

begin
    # your code that attempts to login the user
rescue BCrypt::Errors::InvalidHash
  flash[:error] = 'We recently adjusted the way our passwords are stored. Please click the "forgot username or password?" link to re-establish your password. Thank you for your understanding!'
  redirect_to password_resets_url
end 

J'espère que cela t'aides.

10
nfriend21