我正在努力完成一个项目。我正在研究用户模型。 当我注册时一切似乎都正常。但是当我尝试登录同一成员(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,但这也适用于其他哈希算法。