The BCrypt Gem
Tags: ruby, rails, beginners, programming
Published: 2023-03-07 02:56:12

When creating an application you may want your users to create an account, so they can log in and access a version tailored to them. Take Instagram for example, when a user logs in their feed is populated by photos from people they are friends with and their profile is filled with their bio and photos that they uploaded. Being able to have a user log in is a very important aspect of most modern applications, but you need a way to make sure only that a user can log in to their account and not just anyone. That is where a password comes into the picture. When creating an account, an individual will also create a password, so when they log in with their unique username or email they also insert the password they created and if those are equal to what is stored in the database they will have successfully logged in. However, there is an issue with storing passwords in the database as plain text because it is not very secure and could be easy for a hacker to gain access to your database and all your users' information. The `BCrypt` gem offers a solution to avoid that problem.

##What is BCrypt?
`BCrpyt` is a Ruby gem that will encrypt a user's password so it is not saved in plain text in the database and is therefore more secure. It does this by hashing the inputted password. You may be asking what a hashing is, and it is taking an input and putting it through a function that will change the input into a completely new output based on methods within the function. The outputs are always the same if given the same input. 
```ruby
def simple_hash(input)
   input.bytes.reduce(:*)
end
```
Above is a simple hash that will take your input and convert it into a number. If you were to use the input "hello" no matter how many times you input it you will always get 13599570816 as your output.
```ruby
input1 = "hello"
simple_hash(input1)
# => 13599570816

input2 = "bcrypt"
simple_hash(input2)
# => 1738711408896
```
BCrypt has a hashing method, which is more complex and will always return a string of a fixed length. Some properties of BCrypt is that it will hash inputs that are similar to very different outputs this helps avoid collisions(differing inputs that have the same output). Also BCrypt being a cryptographic hash means that it is virtually impossible to reverse engineer the input based on an output.

One other important thing BCrypt does is that it salts our results from the hash, which means it appends a 29 length string from its salt method and adds it to the front of the hash. It does this in order to avoid the issue of a rainbow table, which experienced hackers may create, and it lists the outputs of the most common passwords.

##Using BCrypt
In order to begin using BCrypt you will need to include it in the gemfile.
```ruby
gem 'bcrypt'
```
After adding it make sure to run `bundle install` in the terminal to ensure your application has access to BCrypt methods. Rails makes it very simple to use BCrypt. The most important step is to add the `has_secure_password` macro to whichever model has the password, in this case the user model.
```ruby
class User < ApplicationRecord
   has_secure_password
end
```
In order for it to work properly you need to have a column in your database labeled `password_digest`. When you create a new user instance with a password, BCrypt will hash and salt the password and save the result in the `password_digest` column. If you also create it with a password_confirmation it will check to make sure they are equal before doing so. Now you may be wondering what do you do when you want the user to log in. How do you compare what the user inputs to what is in the password_digest column. Luckily BCrypt has a way to do that for us.
```ruby
class SessionsController < ApplicationController
  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: { error: "Invalid username or password" }, status: :unauthorized
    end
  end
end
```
When a user logs in on the frontend the create method above will occur in the `SessionsController`. The `&.authenticate` method which is from BCrypt will check if the user is not `nil`, and if it isn't it will take the password and run it through the hash method to check whether the output is equal to what is in the password_digest column. If it is then the user will be saved to that session and rendered. Now the user should be logged in and have access to their tailored version of the application.

##Conclusion
BCrypt is a gem that we can use in rails that gives us a much simpler way to deal with saving passwords and user authentication. It is also much safer and provides a much needed solution to just saving the password in the database as inputted by the user. It provides us with many helpful methods and shortcuts to make it possible.

###Resources 
* [The BCrypt Gem](https://github.com/bcrypt-ruby/bcrypt-ruby)