Search code examples
ruby-on-railsruby-on-rails-4bcryptbcrypt-ruby

Correct practice for using Bcrypt


This guide shows how to use Bcrypt with Rails, but it differs significantly in implementation from this Rails documentation on Bcrypt.


Guide version

Set password

def password=(password)
  self.password_digest = BCrypt::Password.create(password)
end

Authenticate password

def is_password?(password)
  BCrypt::Password.new(self.password_digest) == password
end

But the documentation does the same thing using built in methods.


Documentation version

Set password

Setting user.password or setting both user.password and user.password_confirmation values, then calling user.save will invoke some callbacks from Bcrypt which will take the password values and generate the digest and save that in the database.

user.password = 'mUc3m00RsqyRe' 
user.password_confirmation = 'mUc3m00RsqyRe' 
user.save 

Authenticate password

The method user.authenticate(password) will return false or the instance variable of user depending on whether or not the password argument matches user.password_digest.

user.authenticate('notright')
user.authenticate('mUc3m00RsqyRe')

Questions

  • I had always used the documentation version, since I saw it first, but does the guide follow some better practice?

  • Why does the guide rewrite the wheel? That seems very un-Railsy.

  • Is this just a difference in versions of Bcrypt or Rails?


Solution

  • The correct way is to use has_secure_password (the documented method) which was available since Rails 3. Maybe the guide was based on a practice prior to Rails 3?