Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to encrypt password with has_secure_password in Rails 4.2

I've an API and I installed the next gem

 gem 'bcrypt' 

And into my user model I specific that:

has_secure_password

My DataBase Have a field with name

password_digest

And when run the seeders Yea the password is encrypted, But when try to create a new user from my method the password is normal, This my method for create new user

def self.from_auth(data)
    User.where(email: data[:email]).first_or_create do |user|
        user.email = data[:info][:email]
        user.name = data[:info][:name]
        user.provider = data[:info][:provider]
        user.uid = data[:info][:uid]
        user.password_digest = data[:info][:password]
    end
end

Thanks :)

like image 786
Rul Avatar asked Feb 13 '16 18:02

Rul


People also ask

How do I encrypt my username and password?

If you send the encryption key from the server to the client or the other way around you need to encrypt your symmetric encryption key. The easiest way to do this would be to use TLS. If you use TLS, then the data as well as key are encrypted, so you don't need to encrypt it yourself.

Should password be encrypted in frontend or backend?

Frontend or Backend? The backend. If you only hash them in the frontend, you are vulnerable to a pass the hash attack. The reason that you hash passwords in your database is to prevent an attacker who already compromised your database from using those passwords.

What is Password_digest?

The has_secure_password method encrypts passwords by hashing and salting the passwords and generate 'password_digest'. Please read Wikepedia on how bcrypt works. The has_secure_password method in turn gives you, #authenticate method, which you can use to authenticate passwords.


2 Answers

Do not write the password_digest attribute directly. Use password (and probably password_confirmation) instead and Rails will do the magic for you.

Change

user.password_digest = data[:info][:password]

to

user.password              = data[:info][:password]
user.password_confirmation = data[:info][:password]

I advise to read the docs for has_secure_password.

like image 75
spickermann Avatar answered Nov 15 '22 04:11

spickermann


The password is not being saved as a bcrypt hash.

From the bycrypt documentation

https://github.com/codahale/bcrypt-ruby

require 'bcrypt'

my_password = BCrypt::Password.create("my password")#=> "$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa"

my_password.version              #=> "2a"
my_password.cost                 #=> 10
my_password == "my password"     #=> true
my_password == "not my password" #=> false

my_password = BCrypt::Password.new("$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa")
my_password == "my password"     #=> true
my_password == "not my password" #=> false

So your code to store your user's password hash would look this

def self.from_auth(data)
  User.where(email: data[:email]).first_or_create do |user|
    user.email = data[:info][:email]
    user.name = data[:info][:name]
    user.provider = data[:info][:provider]
    user.uid = data[:info][:uid]
    user.password_digest = BCrypt::Password.create(data[:info][:password])
  end
end

Then you can test it like the documentation says http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html

like image 38
strongjz Avatar answered Nov 15 '22 05:11

strongjz