"BCrypt::erreurs:: InvalidHash" lors de la connexion

je suis en train de terminer un projet. Je travaille avec des modèles utilisateurs. Quand je m'inscris, tout semble ok . Mais quand j'essaie de signer avec le même membre, j'obtiens cette erreur.

Nous sommes désolés, mais quelque chose s'est mal passé. heroku journaux le fichier affiche l'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 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:migrate, heroku restart.. il n'y a pas de changement.

40
demandé sur Ben Lee 2012-06-14 20:56:40

2 réponses

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

basé sur les commentaires, il semble que vous venez de créer l'utilisateur à la fois le has_secure_password n'était pas là, donc le digest de mot de passe n'a jamais été stocké. Rechercher dans la base de données, vous verrez probablement que password_digest est vide pour l'utilisateur. Retirez l'utilisateur de la base de données et recréez avec votre nouveau code de travail et cela devrait fonctionner.

Tout en discutant avec dans le commentaires cependant, j'ai fait un (incorrect) deviner pourquoi les mots de passe seraient erronés, et j'ai déjà écrit l'explication. Donc ici, c'est pour tout visiteur futur qui a ce problème, même si cela 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 ne parvenez pas à re-hachage des mots de passe dans BCrypt. Puisque vous n'avez pas accès aux mots de passe originaux (ou du moins vous ne devriez pas...), c'est un peu laide pour changer parce que vous avez à utiliser BCrypt et le schéma d'authentification original. Par exemple, si vous utilisiez SHA1 avant et maintenant utiliser BCrypt, vous devez traiter le hash de mot de passe SHA1 le mot de passe en clair pour l'entrée BCrypt. Par exemple, vous pouvez créer un BCrypt digérer 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 basé sur le mot de passe sha1 hashes que vous avoir accès de.

Vous authentifier 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 fonctionne pour d'autres algorithmes de hachage.

73
répondu Ben Lee 2012-06-14 17:37:30

j'avais déjà des utilisateurs en direct, et de même déjà enregistré des mots de passe non cryptés dans la base de données. Une fois que j'ai commencé à utiliser bcrypt, il 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 attraper l'erreur et inviter les utilisateurs de l'héritage à 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 

Espérons que cette aide.

9
répondu nfriend21 2014-11-06 15:30:47