Devise gem comes with a lot of extra features you don’t need. What happens is you end up learning everything about using a specific gem and neglect to understand how to learn how to create an app with rails. First a few things on authentication. Your app should never know your password, it shouldn’t be able to find it or even decrypt it.
You should save your password as a One-way hash. So we don’t decrypt it, but instead turn it into a string, stored as a hash, and match those hashes. That is how password authentication works, a one way authentication. Other methods are more prone to attack.
Say we already have a basic user class with some basic attributes.
1- We need to add a column to store and keep the long token, we must call it password_digest since we are using ruby has_secure_password. (shown later)
rails g migration add_password_digest_to_users
in the migration file
add_column :users, :password_digest, :string
2- Go to your User model and add this line, has_secure_password
3- Add gem ‘bcrypt’, version 3.0.1. This gem has the library that does the actual hashing. errors might arise make sure to use the right version. There is a lot of math involved in hashing algorithms, bcrypt comes equipped. Remember to bundle install.
Now we can test it out on rails console.
>> u = User.new
>> u.username = ‘bob’
>> u.save => gives you false, why?
>> u.errors => password cant be blank
This occurs because has_secure_password has some rails built in validations. Once again rails is doing more than we want. To bypass this is just add ‘validations: false’ to the User class
has_secure_password validations: false
>> u.save => true
The has_secure_password gives us the password setter method
>> u.password = ‘password’
– If you look at the SQL statements created by the above. You see it didn’t save password but the password_digest. Password is a virtual attribute, it’s a setter, and it allows us to set values into the password digest. Where it automatically hashes it for us using bcrypt.
So in the database you will see some long crazy string. This is the result of our one way hash. So we have a setter method, but do we have a getter method? The answer is no.
Log out of the rails console and relog back in.
>> u= User.find_by username: ‘bob’
>> u.password => nil
You might have seen a value for u.password before you logged out of rails console before but that is because it was ‘in memory’.
So now knowing this, how do we authenticate our application?
We just performed a one way hash on a string. Which produces our really long token, and if those tokens match then it means those strings are correct.
– has_secure_password also gives us
>> u.authenticate(‘teststring’) method, which just gives us true or false. If the hash tokens don’t match they return false. If they match they return the user object, which evaluates to true.
=> user object…
That’s the way we can use has_secure_password to introduce authentication to our rails app.