Skip to main content
 首页 » 编程设计

ruby-on-rails之rails : "BCrypt::Errors::InvalidHash" when trying to sign in

2024年06月20日19duanxz

我正在努力完成一个项目。我正在研究用户模型。 当我注册时一切似乎都正常。但是当我尝试登录同一成员(member)时,我收到此错误。

很抱歉,出了点问题。 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 哈希(包括该字段为空的情况)。

根据评论,看起来您刚刚创建用户时 has_secure_password 不存在,因此密码摘要从未被存储。查看数据库,您可能会发现该用户的 password_digest 为空。从数据库中删除用户并使用新的工作代码重新创建,它应该可以工作。

尽管在评论中讨论时,我对密码为何错误做出了(错误的)猜测,并且我已经写下了解释。因此,这里适用于任何遇到此问题的 future 访问者,即使它并不直接适用于此处:

<小时 />

当您从使用 SHA1 或其他算法切换到 BCrypt 但无法在 BCrypt 中重新哈希密码时,通常会发生这种情况。由于您无权访问原始密码(或者至少您不应该...),因此切换有点难看,因为您必须同时使用 BCrypt 和原始身份验证方案。例如,如果您之前使用 SHA1,现在使用 BCrypt,则必须将 SHA1 密码哈希视为 BCrypt 输入的纯文本密码。例如,您可以创建如下所示的 BCrypt 摘要:

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

然后,您可以根据您确实有权访问的 sha1 密码哈希创建 bcrypt password_digests。

您将像这样进行身份验证:

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

我在上面的示例中使用了 SHA1,但这也适用于其他哈希算法。