diff --git a/README.md b/README.md index fd1db053..6603eebe 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Devise is a flexible authentication solution for Rails based on Warden. It: It's composed of 10 modules: -* [Database Authenticatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/DatabaseAuthenticatable): encrypts and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication. +* [Database Authenticatable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/DatabaseAuthenticatable): hashes and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication. * [Omniauthable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Omniauthable): adds OmniAuth (https://github.com/intridea/omniauth) support. * [Confirmable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Confirmable): sends emails with confirmation instructions and verifies whether an account is already confirmed during sign in. * [Recoverable](http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Recoverable): resets the user password and sends reset instructions. @@ -174,7 +174,7 @@ member_session ### Configuring Models -The Devise method in your models also accepts some options to configure its modules. For example, you can choose the cost of the encryption algorithm with: +The Devise method in your models also accepts some options to configure its modules. For example, you can choose the cost of the hashing algorithm with: ```ruby devise :database_authenticatable, :registerable, :confirmable, :recoverable, stretches: 20 diff --git a/lib/devise.rb b/lib/devise.rb index 4652c1ab..dca9af6c 100644 --- a/lib/devise.rb +++ b/lib/devise.rb @@ -61,7 +61,7 @@ module Devise mattr_accessor :rememberable_options @@rememberable_options = {} - # The number of times to encrypt password. + # The number of times to hash the password. mattr_accessor :stretches @@stretches = 10 @@ -146,7 +146,7 @@ module Devise mattr_accessor :timeout_in @@timeout_in = 30.minutes - # Used to encrypt password. Please generate one with rake secret. + # Used to hash the password. Please generate one with rake secret. mattr_accessor :pepper @@pepper = nil diff --git a/lib/devise/encryptor.rb b/lib/devise/encryptor.rb index 751db106..19651d7b 100644 --- a/lib/devise/encryptor.rb +++ b/lib/devise/encryptor.rb @@ -9,14 +9,14 @@ module Devise ::BCrypt::Password.create(password, cost: klass.stretches).to_s end - def self.compare(klass, encrypted_password, password) - return false if encrypted_password.blank? - bcrypt = ::BCrypt::Password.new(encrypted_password) + def self.compare(klass, hashed_password, password) + return false if hashed_password.blank? + bcrypt = ::BCrypt::Password.new(hashed_password) if klass.pepper.present? password = "#{password}#{klass.pepper}" end password = ::BCrypt::Engine.hash_secret(password, bcrypt.salt) - Devise.secure_compare(password, encrypted_password) + Devise.secure_compare(password, hashed_password) end end end diff --git a/lib/devise/models/database_authenticatable.rb b/lib/devise/models/database_authenticatable.rb index 27a8646d..2816a813 100644 --- a/lib/devise/models/database_authenticatable.rb +++ b/lib/devise/models/database_authenticatable.rb @@ -7,8 +7,8 @@ module Devise end module Models - # Authenticatable Module, responsible for encrypting password and validating - # authenticity of a user while signing in. + # Authenticatable Module, responsible for hashing the password and + # validating the authenticity of a user while signing in. # # == Options # @@ -37,7 +37,9 @@ module Devise [:encrypted_password] + klass.authentication_keys end - # Generates password encryption based on the given value. + # Generates a hashed password based on the given value. + # For legacy reasons, we use `encrypted_password` to store + # the hashed password. def password=(new_password) attribute_will_change! 'password' @password = new_password @@ -142,11 +144,11 @@ module Devise protected - # Digests the password using bcrypt. Custom encryption should override + # Hashes the password using bcrypt. Custom hash functions should override # this method to apply their own algorithm. # # See https://github.com/plataformatec/devise-encryptable for examples - # of other encryption engines. + # of other hashing engines. def password_digest(password) Devise::Encryptor.digest(self.class, password) end diff --git a/lib/devise/strategies/database_authenticatable.rb b/lib/devise/strategies/database_authenticatable.rb index 42880acf..3d8f4072 100644 --- a/lib/devise/strategies/database_authenticatable.rb +++ b/lib/devise/strategies/database_authenticatable.rb @@ -6,15 +6,15 @@ module Devise class DatabaseAuthenticatable < Authenticatable def authenticate! resource = password.present? && mapping.to.find_for_database_authentication(authentication_hash) - encrypted = false + hashed = false - if validate(resource){ encrypted = true; resource.valid_password?(password) } + if validate(resource){ hashed = true; resource.valid_password?(password) } remember_me(resource) resource.after_database_authentication success!(resource) end - mapping.to.new.password = password if !encrypted && Devise.paranoid + mapping.to.new.password = password if !hashed && Devise.paranoid fail(:not_found_in_database) unless resource end end diff --git a/lib/generators/templates/devise.rb b/lib/generators/templates/devise.rb index 818eebe5..64a22c89 100644 --- a/lib/generators/templates/devise.rb +++ b/lib/generators/templates/devise.rb @@ -92,16 +92,16 @@ Devise.setup do |config| # ==> Configuration for :database_authenticatable # For bcrypt, this is the cost for hashing the password and defaults to 10. If - # using other encryptors, it sets how many times you want the password re-encrypted. + # using other algorithms, it sets how many times you want the password to be hashed. # # Limiting the stretches to just one in testing will increase the performance of # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use # a value less than 10 in other environments. Note that, for bcrypt (the default - # encryptor), the cost increases exponentially with the number of stretches (e.g. + # algorithm), the cost increases exponentially with the number of stretches (e.g. # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). config.stretches = Rails.env.test? ? 1 : 10 - # Set up a pepper to generate the encrypted password. + # Set up a pepper to generate the hashed password. # config.pepper = '<%= SecureRandom.hex(64) %>' # Send a notification email when the user's password is changed @@ -201,11 +201,11 @@ Devise.setup do |config| # config.sign_in_after_reset_password = true # ==> Configuration for :encryptable - # Allow you to use another encryption algorithm besides bcrypt (default). You can use - # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1, - # :authlogic_sha512 (then you should set stretches above to 20 for default behavior) - # and :restful_authentication_sha1 (then you should set stretches to 10, and copy - # REST_AUTH_SITE_KEY to pepper). + # Allow you to use another hashing or encryption algorithm besides bcrypt (default). + # You can use :sha1, :sha512 or algorithms from others authentication tools as + # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20 + # for default behavior) and :restful_authentication_sha1 (then you should set + # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper). # # Require the `devise-encryptable` gem when using anything other than bcrypt # config.encryptor = :sha512 diff --git a/test/models/database_authenticatable_test.rb b/test/models/database_authenticatable_test.rb index 5daca424..8c12d93c 100644 --- a/test/models/database_authenticatable_test.rb +++ b/test/models/database_authenticatable_test.rb @@ -92,28 +92,28 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase assert user.respond_to?(:password_confirmation) end - test 'should generate encrypted password while setting password' do + test 'should generate a hashed password while setting password' do user = new_user assert_present user.encrypted_password end - test 'should support custom encryption methods' do - user = UserWithCustomEncryption.new(password: '654321') + test 'should support custom hashing methods' do + user = UserWithCustomHashing.new(password: '654321') assert_equal user.encrypted_password, '123456' end - test 'allow authenticatable_salt to work even with nil encrypted password' do + test 'allow authenticatable_salt to work even with nil hashed password' do user = User.new user.encrypted_password = nil assert_nil user.authenticatable_salt end - test 'should not generate encrypted password if password is blank' do + test 'should not generate a hashed password if password is blank' do assert_blank new_user(password: nil).encrypted_password assert_blank new_user(password: '').encrypted_password end - test 'should encrypt password again if password has changed' do + test 'should hash password again if password has changed' do user = create_user encrypted_password = user.encrypted_password user.password = user.password_confirmation = 'new_password' diff --git a/test/test_models.rb b/test/test_models.rb index 3c1f1787..d65648d9 100644 --- a/test/test_models.rb +++ b/test/test_models.rb @@ -12,7 +12,7 @@ class UserWithValidation < User validates_presence_of :username end -class UserWithCustomEncryption < User +class UserWithCustomHashing < User protected def password_digest(password) password.reverse