module Devise::Models::DatabaseAuthenticatable

Authenticatable Module, responsible for encrypting password and validating authenticity of a user while signing in.

Options

DatabaseAuthenticable adds the following options to devise_for:

* +pepper+: a random string used to provide a more secure hash. Use
  `rake secret` to generate new keys.

* +stretches+: the cost given to bcrypt.

Examples

User.find(1).valid_password?('password123')         # returns true/false

Public Instance Methods

after_database_authentication() click to toggle source
# File lib/devise/models/database_authenticatable.rb, line 98
def after_database_authentication
end
authenticatable_salt() click to toggle source

A reliable way to expose the salt regardless of the implementation.

# File lib/devise/models/database_authenticatable.rb, line 102
def authenticatable_salt
  encrypted_password[0,29] if encrypted_password
end
clean_up_passwords() click to toggle source

Set password and password confirmation to nil

# File lib/devise/models/database_authenticatable.rb, line 49
def clean_up_passwords
  self.password = self.password_confirmation = nil
end
password=(new_password) click to toggle source

Generates password encryption based on the given value.

# File lib/devise/models/database_authenticatable.rb, line 35
def password=(new_password)
  @password = new_password
  self.encrypted_password = password_digest(@password) if @password.present?
end
update_with_password(params, *options) click to toggle source

Update record attributes when :current_password matches, otherwise returns error on :current_password. It also automatically rejects :password and :password_confirmation if they are blank.

# File lib/devise/models/database_authenticatable.rb, line 56
def update_with_password(params, *options)
  current_password = params.delete(:current_password)

  if params[:password].blank?
    params.delete(:password)
    params.delete(:password_confirmation) if params[:password_confirmation].blank?
  end

  result = if valid_password?(current_password)
    update_attributes(params, *options)
  else
    self.assign_attributes(params, *options)
    self.valid?
    self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
    false
  end

  clean_up_passwords
  result
end
update_without_password(params, *options) click to toggle source

Updates record attributes without asking for the current password. Never allows to change the current password. If you are using this method, you should probably override this method to protect other attributes you would not like to be updated without a password.

Example:

def update_without_password(params={})
  params.delete(:email)
  super(params)
end
# File lib/devise/models/database_authenticatable.rb, line 89
def update_without_password(params, *options)
  params.delete(:password)
  params.delete(:password_confirmation)

  result = update_attributes(params, *options)
  clean_up_passwords
  result
end
valid_password?(password) click to toggle source

Verifies whether an password (ie from sign in) is the user password.

# File lib/devise/models/database_authenticatable.rb, line 41
def valid_password?(password)
  return false if encrypted_password.blank?
  bcrypt   = ::BCrypt::Password.new(encrypted_password)
  password = ::BCrypt::Engine.hash_secret("#{password}#{self.class.pepper}", bcrypt.salt)
  Devise.secure_compare(password, encrypted_password)
end

Protected Instance Methods

password_digest(password) click to toggle source

Digests the password using bcrypt.

# File lib/devise/models/database_authenticatable.rb, line 109
def password_digest(password)
  ::BCrypt::Password.create("#{password}#{self.class.pepper}", :cost => self.class.stretches).to_s
end

Public Class Methods

required_fields(klass) click to toggle source
# File lib/devise/models/database_authenticatable.rb, line 30
def self.required_fields(klass)
  [:encrypted_password] + klass.authentication_keys
end