Authentication from Scratch with Rails 5.2

Stefan Wintermeyer
Sep 18, 2018 · 4 min read

A tutorial to create a simple authentication for your Rails 5.2 application when gems like Devise are too big or too complicated to customize.

Background: Often I use Devise as the one-stop-shop solution. But lately I found myself (again) in a Rails application trying to find out how to customize Devise for the specific needs of that application. Just to realize that I would have saved so much time by just implementing the authentication from scratch by myself.

The groundwork for tutorial was done by Ryan Bates many years ago.

Important: This tutorial works under the assumption that the session encryption of Rails is secure. If you disagree with that assumption you are bright enough to add an additional random token.

Green Field

We start with a fresh Rails application:

Later we are going to redirect to root. So we start with creating an empty root page:

Please add the following code to config/routes.rb :

And some content for that page in the file app/views/home/index.html.erb :


If you like this post I’d like to ask you for a favour:
Create an account at my open-source business network https://www.vutuv.de

Thank you and see you there!


Password Digest

Obviously we do not store the clear text password in the database but a digest of it. For that we need to activate the bcrypt gem in the file Gemfile:

And run bundle afterwords:

User Model

Now we create a User scaffold. Feel free to add any additional fields you might need (e.g. first_name, last_name). I just use email:uniq to store the email address (and create an unique database index) and password:digest to create a password_digest field in the new users table.

The digest part puts some Rails magic into action. The Rails generator creates a password_digest field in the table and asks for an additional password_confirmation in the form and the controllers user_params without you having to do anything extra. has_secure_password in the model takes care of encrypting the password and provides theauthenticate method to authenticate with that password.

Before a first test we need to add some validations in app/models/user.rb to make sure that we have an email address and that it is unique:

Now we can fire up Rails and create a new user in the browser:

Image for post
Image for post
Screencast: Create a new user at http://localhost:3000/users/new

Let’s just check how Rails stores the password digest in the table:

So only the digest is saved. Everything is secure. But we still need to create some sort of login to actually use it.

Sessions

When a user logs in he/she creates a new session. When the same user logs out that session gets destroyed. Therefor we create a sessions controller with three actions:

We put the following code into app/controllers/sessions_controller.rb:

As you can see we use session[:user_id] to store the logged in user id. In case you haven’t worked with sessions yet have a look at https://guides.rubyonrails.org/security.html#sessions

We need to put this code for the form in app/views/sessions/new.html.erb :

Routes

The routes are a bit cumbersome. But we can fix this with this code in config/routes.rb :

Now a user can use http://localhost:3000/login to login and http://localhost:3000/logout to logout. Much easier for everybody.

current_user

In most Rails applications the logged in user is available with a current_user helper. This come handy too if you want to use an authorization gem like cancancan. The most popular way to add this functionality is this code in app/controllers/application_controller.rb:

To put it into use we change the content of app/views/home/index.html.erb:

The End

And here is the screencast where I log in with my account and log out afterwards:

Image for post
Image for post
Screencast: Log in and Log out

Shameless Plug

Do you want to learn more about Rails 5.2? Buy my book at https://www.amazon.com/Learn-Rails-5-2-Accelerated-Development/dp/148423488X

In case you need consulting or training:
https://www.wintermeyer-consulting.de

Contact Information

Email: sw@wintermeyer-consulting.de
Twitter: https://twitter.com/wintermeyer

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store