Rails Bcrypt Gem
Published: 2023-01-31 21:44:00

Rails’ Bcrypt Gem

As developers, when we  are making web applications we always dream about other people using them. We think about how users will interact with our applications, and how they will ultimately use it to make their lives better. One important aspect, maybe the most important, is the security of our users. Whenever we make software we must always think about the security of our user’s information. Wrongdoers are always ready to take advantage of applications that have little to no security. When using Rails for the backend of your web application we can use the Bcrypt gem to better protect our user’s password. 

How does Bcrypt work? The bcrypt gem uses a password hashing function that is computationally slow which makes it difficult for malicious hackers to attack our users’ passwords. When a new user signs up for our application bcrypt hashes their password and stores that hash in the database. From that point on when the user wants to login, they input their password, it then gets hashed and compared to the hashed password in the database, and if it matches the hashed password in the database they are then signed in. 

In order to apply this to our rails application we first make sure that our user model has the macro has_secure_password. This macro gives us access to the password and password_confirmation methods as well as the authenticate method. Our user model must also have a password_digest attribute and that is what automatically adds the password and password_confirmation fields to our database. 

class User < ApplicationRecord
   has_secure_password
   validates :username, presence: true, uniqueness: true
end

  def create
       user = User.create!(user_params)
       render json: user, status: :created
   end


   private
      
   def user_params
       params.permit(:username, :password, :password_confirmation, :image_url)
   end

Take a look at the user_params method. This method is using strong params to permit username, image_url but also password, and password_confirmation. This is due to the password_digest attribute on the user model. 

Now that the create action is set up we can move on to setting up the login functionality. Think about how this process would work step by step. A user would input their username and password and if the information is correct they are then signed in. 

def create
       user = User.find_by(username: params[:username])
       if user&.authenticate(params[:password])
           session[:user_id] = user.id
           render json: user, status: :created
       else
           render json: { errors: ["Incorrect username or password"] }, status: :unauthorized
       end
   end



The create action in our sessions controller completes the first step, find a user in our database with the username the user input. If that user exists and their password is authenticated they are then logged in. The authenticate method is doing the final step of checking to see if the password that the user input matches the one in the database. If for whatever reason authentication fails the user will not be logged in and instead will see the error “Incorrect username or password”. 

Now we have everything in place to have users that can sign up, log in and use our applications all with a strong level of security thanks to bcrypt.