Module: ActiveRecord::SecurePassword::ClassMethods

Defined in:
lib/active_record/secure_password.rb

Instance Method Summary collapse

Instance Method Details

#has_secure_password(options = {}) ⇒ Object

Adds methods to set and authenticate against a BCrypt password. This mechanism requires you to have a password_digest attribute.

Validations for presence of password on create, confirmation of password (using a password_confirmation attribute) are automatically added. If you wish to turn off validations, pass validations: false as an argument. You can add more validations by hand if need be.

If you don’t need the confirmation validation, just don’t set any value to the password_confirmation attribute and the the validation will not be triggered.

You need to add bcrypt-ruby (~> 3.0.0) to Gemfile to use #has_secure_password:

gem 'bcrypt-ruby', '~> 3.0.0'

Example using Active Record (which automatically includes ActiveRecord::SecurePassword):

# Schema: User(name:string, password_digest:string)
class User < ActiveRecord::Base
  has_secure_password
end

user = User.new(name: 'david', password: '', password_confirmation: 'nomatch')
user.save                                                       # => false, password required
user.password = 'mUc3m00RsqyRe'
user.save                                                       # => false, confirmation doesn't match
user.password_confirmation = 'mUc3m00RsqyRe'
user.save                                                       # => true
user.authenticate('notright')                                   # => false
user.authenticate('mUc3m00RsqyRe')                              # => user
User.find_by(name: 'david').try(:authenticate, 'notright')      # => false
User.find_by(name: 'david').try(:authenticate, 'mUc3m00RsqyRe') # => user


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/active_record/secure_password.rb', line 45

def has_secure_password(options = {})
  # Load bcrypt-ruby only when has_secure_password is used.
  # This is to avoid ActiveRecord (and by extension the entire framework)
  # being dependent on a binary library.
  begin
    gem 'bcrypt-ruby', '~> 3.0.0'
    require 'bcrypt'
  rescue LoadError
    $stderr.puts "You don't have bcrypt-ruby installed in your application. Please add it to your Gemfile and run bundle install"
    raise
  end

  attr_reader :password

  include InstanceMethodsOnActivation

  if options[:validations] == true || options[:validations].nil?
    validates_confirmation_of :password, :if => lambda { |m| m.password.present? }
    validates_presence_of     :password, :on => :create
    validates_presence_of     :password_confirmation, :if => lambda { |m| m.password.present? }

    before_create { |r| raise "Password digest missing on new record" if r.password_digest.blank? }
  end

  if respond_to?(:attributes_protected_by_default)
    def self.attributes_protected_by_default #:nodoc:
      super + ['password_digest']
    end
  end
end