我正在实施验证方案,并且正在使用bcrypt-ruby gem。
require 'bcrypt'
class User < ActiveRecord::Base
include BCrypt
attr_accessor :password
attr_accessible :name, :email, :password, :password_confirmation
validates :password, :presence => true, :on => :create,
:confirmation => true,
:length => {:within => 6..12}
before_save :encrypt_password
def has_password?(submitted_password)
self.encrypted_password == submitted_password # this calls a method in bcrypt
# File lib/bcrypt.rb, line 171
# def ==(secret)
# super(BCrypt::Engine.hash_secret(secret, @salt))
# end
end
private
def encrypt_password
self.encrypted_password = Password.create(password, :cost => 5)
end
end
现在在控制台中我创建了一个新用户
>> user = User.create!(:name => "test", :email => "test@test.com", :password => "foobar", :password_confirmation => "foobar")
=> #<User id: 1, name: "test", email: "test@test.com", created_at: "2011-06-23 05:00:00", updated_at: "2011-06-23 05:00:00", encrypted_password: "$2a$10$I7Wy8NDMeVcNgOsE3J/ZyubiNAESyxA7Z49H4p1x5xxH...">
如果我检查密码是否有效,我会执行以下操作:
>> user.has_password?("foobar")
=> true
但如果我从数据库中获取用户,则会失败:
user = User.find(1)
user.has_password?("foobar")
=> false
为什么会发生这种情况,如何实施bcrypt才能使其发挥作用?
提前谢谢。
答案 0 :(得分:0)
我的猜测是,由于encrypted_password作为字符串而不是BCrypt :: Password存储在数据库中,因此您不会调用BCrypt的==,而是调用String的==。您必须围绕字符串哈希值实例化密码实例。那就是我要看的地方。
答案 1 :(得分:0)
如here所述,您必须使用Bcrypt的密码类才能使用==
def has_password?(submitted_password)
Bcrypt::Password.new(self.encrypted_password) == submitted_password
end