Storing Passwords in Sinatra!
Published: 2021-02-28 19:13:08

I recently completed my Sinatra project by creating an application which allows a user to create a custom Among Us character as well as view other characters which have been created by the various users on the application.  

As part of this project, we were required to create a Users class which can securely login, and therefore, we needed to create a way to store the various users’ passwords securely, as well as authenticate users.  This blog will expand further into the following topics:

1. Storing passwords securely with the Bcrpyt gem and password_digest; and
2. Has_secure_password and authenticate method.

Storing Passwords

As a software engineer, building applications with secure password protection is incredibly important as users need to be able to trust the applications they use to protect their data.  Accordingly, one of the worst things a software engineer can do is store a user’s password as plain text within the application’s database, and that is where hashing algorithms come in handy!

The algorithm will manipulate the data inputted by the user so that it cannot be un-manipulated, and therefore becomes largely inaccessible to hackers and future developers.  Additionally, after hashing the password, a “salt” is added, which adds a random string of characters to the hash.  Adding the random string of characters to the hash is very important because if the application gets large enough, you run into the inevitability that two users enter the same password for their respective accounts, and by adding a salt to these hashes they will have unique strings despite entering the same password.

Bcrypt

Bcrypt is an open-source gem accessible to software engineers to help with this process.  This gem stores a salted and hashed version of the users’ passwords within the database, using a column called “password_digest” (implemented as shown in the code snippet below).  The password_digest is used over a simple “password” because this avoids a password from being displayed in plain text and is encrypted prior to being stored in the database.  Although this does not completely mitigate a hacker’s ability to access the passwords, it creates another layer of protection against them.  

```
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |u|
      u.string :username
      u.string :password_digest
    end
  end
end 
```


has_secure_password

The ActiveRecord macro “has_secure_password” gives software engineers access to new methods and is called like a normal ruby method, working together with bcrypt to secure passwords without displaying them in plaint text format by tasing and salting them (implemented as shown in the code snippet below).  

``` 
class User < ActiveRecord::Base
    
    has_secure_password
end 
```

In addition to salting and hashing plain-text passwords, the has_secure_password method gives the developer the “authenticate” method, which can be used to authenticate passwords.  The authenticate method works by taking in a string as an arguments and turning it into a salted and hashed version.  It then compares the salted and hashed version with the user’s stored salted and hashed password contained in the database.  Should the two versions match, the User instance will be returned, if not, a false will be returned.

I hope I have provided some clarity as to how a Sinatra database stores passwords securely utilizing the b-crypt gem and has_secure_password, for more information on these techniques feel free to visit (https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html).