If you have used the BCrypt Ruby gem, you might be familiar with the traditional way of implementing BCrypt which involves adding “has_secure_password” to the user model, but what exactly does “has_secure_password” do? The line “has_secure_password” adds methods that set and verify passwords using ActiveModel::SecurePassword public methods. When building a Rails app without an database (active record), your models will not inherit the public methods within Active Method unless you manually add the library by adding the following code to your PORO (model):
Alternatively we can use BCrypt methods to manually handle our encryption and verification without using “has_secure_password” or Active Model methods.
But wait- in what scenario would you need to authenticate a user without having a database of users? User data can be stored on another app such as an .json API server, specifically a “username” and “password_digest.”
Raw text passwords should NEVER be transmitted, so how do we “verify” the password we are given by a user when attempting to login without sending the raw password to the API server? The obvious answer might to be “encrypt the raw password and send it to the API server” and this would work for creating a user but because of Bcrypt uses a unique “salt” factor for each encryption, encrypting the same password twice will yield unique password_digests. Instead of passing a digest to the API server, we can fetch the existing digest and compare this within our app against the password a user enters.
BCrypt normally uses .is_password? method which actually contains:
if BCrypt::Password.new(“password_digest”) == raw_password
which will return a true or false, true being the raw_password matching the digest, or false if it does not.
With this we can handle client side authentication without transmitting raw password data to and from a remote server.