Utilizing the bcrypt Ruby gem

Jacob Kenny
4 min readJun 11, 2020

--

I think it’s fair to say that every now and then every person finds themself struggling through a problem, finally reaches asolution, and then thinks to themself: “Wow I am such an idiot.” I think it may also be fair to say that this happens to me more than most. I wanted to write about one of those moments in particular, in the hopes that someone who is struggling through the same problem will find and read this post, and then realize that they too, are an idiot.

When in the process of creating a project, it’s common practice to leave any implementation of a login process until the very end — and for good reason. Logging in with “123” as both the username and password only takes two seconds, but those two seconds really start to add up when you have to log in to your own app for what seems like a thousand times just to work on something from a user-specific page. So often any sort of password encryption is the absolute last thing that one might do — especially since an app that runs locally really has no need to consider the security of users’ passwords (and other sensitive information). However, once you’ve deployed your application, you are then ultimately responsible for the security of whatever information that your users will input into your site. Even if your mom and dad are your only users, if someone with bad intentions were to locate your database, and all of the passwords are stored there in plain text that is no bueno.

For a rails app, this is where the bcrypt gem comes in. The gem utilizes a hashing algorithm, the details of how it works are far outside the scope of this post, however the gem writer sums it up as such: “Hash algorithms take a chunk of data (e.g., your user’s password) and create a “digital fingerprint,” or hash, of it. Because this process is not reversible, there’s no way to go from the hash back to the password.”

Getting started is simple enough — the first step is to include the bcrypt gem in your gemfile. Commonly the gem is already there, and just needs to be un-commented, but if it’s not there, the text to add the gemfile can be found at rubygems.org. Once the gem is listed in the gemfile, simply run the command ‘bundle install’. The second step is to update your database. In my case, I had a user model with a password attribute which was the cause for my concern. To update the database run the command ‘rails g migration’ and be sure to give the file a descriptive name such as “add_password_digest_to_users.” I suggest having your migration file look something like the one shown below:

When developing locally, it would also probably be fine to have the migration simply rename the ‘password’ column to ‘password_digest’ however that almost certainly will create some issues with any users that you’ve instantiated during the process of developing. Then, the only thing left to do is to go to the file in which the model is defined, and add the line ‘has_secure_password’ in the same place where you would declare any other associations.

With those three steps the bcrypt gem is set up and ready to use, but as I mentioned above, I had a difficult time actually getting it to work as intended. I was attempting to create a user to test things out by inputting the following line in the Rails console:

User.create(username: ‘JacobK’, password_digest: ‘123’)

But, when I went to view my new user I was greeted with this:

See the problem here?

I was not hoping to see my password digest listed right there with exactly the same password that I had just created! So what needs to change?

Honestly it is a simple change, and in hindsight, the documentation is clear, it’s just that in my haste to get it working I was doing something that was not only unnecessary, but was also the root cause of my problem. When creating the user, you actually just need to give it a ‘password’ attribute, not “password_digest”, even though the column is titled “password_digest”. Then the gem takes care of the rest. So (after trying many other things in a variety of other files to fix the problem) I input the command: User.create(username: ‘Jacob’, password: 123) and was greeted with this once I went to view my newly created user:

Much better

That password digest listed there was generated from the string ‘123’ that I had input in my command. I know it’s working because even if someone were to locate my database online, and saw that user, when they would go to log in to my site with the username, and that password_digest it would not work — take my word for it, or better yet do your own research and testing.

With this gem there are certainly other useful methods that are included such as the authenticate method, but for that I suggest that you stop reading this post ,and seek out more official documentation. As always, please message me if I’ve made any mistakes, overlooked something, or just to say hi.

Disclaimer: Any mention of bcrypt is in regards to the bcrypt gem for Ruby on Rails version 3.1.7

--

--

No responses yet