Rails> Password Encryption Design

I am trying to implement a method that allows me to change the password from another service outside by any means.

# Profile password change def change_password(oldpass, newpass) pepper = nil cost = 10 # Encrypt plain text passwords encrypt_old = ::BCrypt::Password.create("#{oldpass}#{pepper}", :cost => cost).to_s # Validate old if self.encrypted_password == encrypt_old encrypt_new = ::BCrypt::Password.create("#{newpass}#{pepper}", :cost => cost).to_s self.encrypted_password = encrypt_new self.save else Logger.new("Wrong old password!") end end 

It seems my password encryption is wrong. oldwall contains plain text of the old password. I need a hash file to see if it matches the current password, and then allow a new password. However, all I get is the wrong password.

Redesigned:

 def change_password(oldpass, newpass) if valid_password?(oldpass) password = newpass save return true else return false end end 
+4
source share
2 answers

You do not need to encrypt the password yourself if you are in the application or in the Rails console.

Just upgrade the user as follows and Devise will take care of that.

 user.password = new_password user.save 

Then Devise will encrypt the password and save it. You just need to make sure user.password_confirmation nil . If password_confirmation is something else, it will be mapped to password .

EDIT

You can check your existing password with: user.valid_password?(old_password)

+12
source

With Devise, you don’t have to bcrypt yourself. By default, it handles this and the change password method. You can look at the source here or just look at config/intitalizers/devise.rb in your Rails application.

Also, if you use the #update_with_password method provided by Devise, you can pass the hash to it like this:

 { :current_password => 'pass', :password => 'pass_new', :password_confirmation => 'pass_new' } 

Or you can omit :password_confirmation if you do not want the user to provide confirmation.

EDIT: I used the wrong field; it should have been "current_password" instead of "old_password".

Here's the method in source for Devise:

  # 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. 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 

View on GitHub

+4
source

All Articles