2012-06-14 52 views
37

Estoy intentando finalizar un proyecto. Estoy trabajando con modelos de usuario. Cuando me suscribo todo parece estar bien. Pero cuando trato de iniciar sesión en el mismo miembro obtengo este error."BCrypt :: Errors :: InvalidHash" al intentar iniciar sesión

Lo sentimos, pero algo salió mal. registros heroku archivo muestra el error como:

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

mi * sessions_controller * es:

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 

y modelo de usuario es:

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 

este es mi 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 

me trataron heroku rake db: migrate, heroku reinicio .. no hay ningún cambio.

+1

nos puedes mostrar su método 'sign_in'? –

+0

editado mi primer mensaje con session.helper en el message.there es el método sign_in – ytsejam

+0

Por si acaso, han hecho que '' install' paquete con joya 'bcrypt-rubí', '3.0.1'' en su 'Gemfile' ? –

Respuesta

67

Esto significa que el hash almacenado en password_digest no es un hash BCrypt válido (incluso si el campo está vacío).

Según los comentarios, parece que acaba de crear el usuario en el momento en que has_secure_password no estaba allí, por lo que el resumen de la contraseña nunca se almacenó. Busque en la base de datos, probablemente verá que password_digest está vacío para ese usuario. Elimine al usuario de la base de datos y vuelva a crear con su nuevo código de trabajo y debería funcionar.

Mientras discutía con los comentarios, hice una conjetura (incorrecta) sobre por qué las contraseñas serían incorrectas, y ya escribí la explicación. Así que aquí es para cualquier visitante futuro que tiene este problema, a pesar de que no se aplica directamente aquí:


Esto suele ocurrir cuando se cambia el uso de SHA1 u otro algoritmo para Bcrypt pero no para volver hash las contraseñas en BCrypt. Como no tiene acceso a las contraseñas originales (o al menos no debería ...), es un poco feo cambiar porque tiene que usar tanto BCrypt como el esquema de autenticación original. Por ejemplo, si estaba usando SHA1 antes y ahora usa BCrypt, debe tratar la contraseña de SHA1 hash como la contraseña de texto sin formato para la entrada de BCrypt. Por ejemplo, puede crear un Bcrypt digerir así:

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

A continuación, puede crear password_digests Bcrypt en base a la contraseña hashes SHA1 que hacer tienen acceso.

Se podría autenticar la siguiente manera:

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

que utiliza SHA1 en los ejemplos anteriores, pero esto va a funcionar para otros algoritmos hash también.

+0

Ben Lee gracias. ahora funciona. me salvaste el día y la noche. – ytsejam

+0

@ytsejam, contento de ayudar –

+0

¡Estaba buscando horas, muchas gracias! – Linus

9

Ya tenía usuarios activos, y también guardé contraseñas no encriptadas en la base de datos. Una vez que comencé a usar bcrypt, esperaba una contraseña encriptada, y cuando no la encontró, produjo este error.

Por lo tanto, he añadido este rescate a detectar el error y pedir a los usuarios heredados para restablecer su contraseña:

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 

Espero que esto ayude.

+1

No creo que sea una buena idea confiar en authenticate() al generar una excepción no documentada; es más limpio solucionarlo al verificar password_digest.empty? antes de llamar a authenticate(). – pdg137

+0

También tengo usuarios existentes (aunque un conjunto pequeño). Actualicé manualmente las contraseñas con 'u = User.find (...); u.password = ""; ¡Ahorre! 'y envíe a todos las contraseñas nuevas. El punto aquí, supongo, es que simplemente actualizando la contraseña a través del modelo, se configura todo correctamente. –

+1

trabajado para mí gracias –

Cuestiones relacionadas