尝试login时出现“BCrypt :: Errors :: InvalidHash”

我正在努力完成一个项目。 我正在与用户模型。 当我注册时,一切似乎都没问题。 但是,当我尝试login相同的成员,我得到这个错误。

我们很抱歉,但是出现了一些问题。 heroku日志文件显示错误为:

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

* sessions_controller *是:

 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 

用户模型是:

 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 

这是我的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 

我试过heroku rake db:migrate,heroku restart ..没有任何变化。

这意味着存储在password_digest中的散列不是有效的BCrypt散列(包括如果该字段为空)。

根据评论,它看起来像你刚刚创build的用户一次has_secure_password不存在,所以密码摘要永远不会被存储。 在数据库中查看,您可能会看到该password_digest为空。 从数据库中删除用户,并重新创build新的工作代码,它应该工作。

虽然在评论中讨论,但是我对密码为什么是错误的做了一个(错误的)猜测,而且我已经写下了解释。 所以在这里,任何未来的访问者都会遇到这个问题,尽pipe这里并不直接适用:


这通常发生在从使用SHA1或其他algorithm切换到BCrypt,但无法重新散列BCrypt中的密码时。 由于您无法访问原始密码(或至less不应该…),因此您必须同时使用BCrypt和原始身份validationscheme,因此切换起来有点难看。 例如,如果您之前使用的是SHA1,现在使用的是BCrypt,则必须将SHA1密码散列作为 BCryptinput的纯文本密码。 例如,你可以像这样创build一个BCrypt摘要:

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

然后,您可以根据您有权访问的sha1密码哈希来创buildbcrypt password_digests。

你会这样authentication:

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

在上面的例子中我使用了SHA1,但是这也适用于其他哈希algorithm。

我已经有活的用户,同样已经将未encryption的密码保存到数据库中。 一旦我开始使用bcrypt,它期待一个encryption的密码,当它没有find它时,就会产生这个错误。

因此,我添加了这个救援来捕捉错误并提示旧用户重置密码:

 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 

希望这可以帮助。