我正在努力完成一个项目.我正在与用户模型合作.

很抱歉,出了点问题.

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

我的目标是:

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

user model是:

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:迁移,heroku重启..没有变化.

推荐答案

这意味着存储在password_digest中的哈希不是有效的BCrypt哈希(包括如果字段为空).

根据这些 comments ,看起来你只是在has_secure_password不存在的时候创建了用户,所以密码摘要从未被存储.在数据库中,您可能会看到password_digest对于该用户是空的.从数据库中删除用户,并使用新的工作代码重新创建,它应该可以工作.

不过,在 comments 中与讨论时,我(错误地)猜测了为什么密码会出错,我已经写下了解释.因此,这是为任何future 的访客,有这个问题,即使它不直接适用于这里:


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

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

然后,您可以基于您有权访问的sha1密码哈希创建bcrypt password_摘要.

您可以这样进行身份验证:

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

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

Ruby-on-rails相关问答推荐

mini_racer gem 0.8.0无法与Ruby 3.1.xBundle 安装

BigDecimals 的总和最终成为整数 [Ruby on Rails]

Rails 3 应用程序的 MySQL 集群 (NDB) 与 MySQL 复制 (InnoDB):优点/缺点?

您将如何在 Ruby on Rails 应用程序中使用 rSpec 测试观察者?

rake assets:precompile try 连接到数据库

在 rails 3 中设置记录器

mongoid 中 embeds_many 和 has_many 的区别

可能在rails中有多态has_one关系?

在 Rails 应用程序中处理大文件上传的最佳方法是什么?

如何检测我的代码是否在 Rails 3 的控制台中运行?

如何在 Ruby on Rails 的内存缓存存储中列出键?

Rails 4模块的未初始化常量

使用 PostgreSQL 的模式和 Rails 创建多租户应用程序

Rspec:如何在控制器规范中分配实例变量

Dotenv 多行变量

ActiveRecord 中多列的索引

使用 heroku 和 namecheap 设置自定义域

使用连接的 Ruby on Rails ActiveRecord 查询

Ruby/Rails CSV 解析,UTF-8 中的无效字节序列

将数组传递到 hidden_​​field ROR