Note:
A more detailed article on this topic can be found here: https://www.nopio.com/blog/authentication-authorization-rails/

Intro

If you have followed through the previous article, then we should now have a basic API for our Books. Since our website now has functions, we should add authentication features so users can sign up and login. This can help us track users and implement authorization later on.

Let’s generate some components needed for this:

rails generate devise:install

Generate the views for the authentication pages:

rails g devise:views

Note:

Devise is the gem (plugin/library for rails) that has a bunch of pre-built functions we can use to implement authentication.

Users

We can now run the follow to generate the User model for our database:

rails generate devise User
rake db:migrate

You should now have a basic login screen for the website! To check, restart your rails server and visit http://localhost:3000/users/sign_in

Click on Sign up and create a user

After you create the user, you should be automatically signed in. Or you can sign in through /users/sign_in. If you are already signed in, it will just take you to the home page. Now we just need a way to let users know that they are signed in.

Navigation Bar

Let’s add a navigation bar at the top of the page for User options like signing in and signing out. Go to /app/views/layouts/ and open up your application’s layout file: application.html.erb. Then change the contents so that it looks like this: https://gist.github.com/mt9304/d2bb86ad1b3e50f28bf4a14b4f344c3b

Now, we can add some CSS to style the page just a bit. Open up /app/assets/stylesheets/ and rename the application.css to application.scss. Then edit the contents in there to include bootstrap and add some styling: https://gist.github.com/mt9304/e9087f054ee8fb773f0180caeb75ab5c

Notes:

The @import bootstrap line lets us use a very popular css library. More information on Bootstrap here: http://getbootstrap.com/

It essentially has a bunch of pre-built styles we can use to make a website so we don’t have to style it from scratch.

When you start the server and look at the website, you should now see a navigation bar at the top with a Dropdown menu for Users at the top right. Right now, clicking it won’t do anything, because we have not added the appropriate JavaScript to handle this action. In this case, we can use Bootstrap’s JavaScript library to help us handle dropdown menues.

Go to /app/assets/javascripts/application.js and add //= require bootstrap-sprockets to the very bottom of the page and save. Now when you click on the User button at the top right, you should be able to see the menu drop down. This should show actions such as Login and Logout. These buttons should work already since the Devise gem has taken care of the authentication functions for us, but since we want users to know when they are logged in, we will make some changes to this menu.

Checking if logged in

Let’s make it so that you will only see the Login button if you are not already signed in. Similarly, the Logout button should only appear if the user is already signed in. To do this, let’s open up the /app/views/layouts/application.html.erb file again and make some changes to the user menu section. (around lined 32):

<% if user_signed_in? %>
<%= link_to "Edit profile", edit_user_registration_path %>
<% else %>
<%= link_to "Sign up", new_user_registration_path %>
<%= link_to "Login", new_user_session_path %>
<% end %>
<% if user_signed_in? %>
<%= link_to "Logout", destroy_user_session_path, method: :delete %>
<% end %>

Your application.html.erb file should now look something like this: https://gist.github.com/mt9304/3a87440097d5de9e16ef40c704270528

Notes:

In Ruby on Rails, the .html part of the file name shows it is an HTML file, and the erb extension at the end let’s the server know that this can accept Ruby code as well. The parts in between the angle bracket/percentage signs (<% some_code %>) are to indicate Ruby code, which is usually programming logic that HTML files would otherwise not be able to use. The brackets without ‘=’ signs like <% some_code %> are indicators of Ruby code that do not need to render anything, while the ‘=’ signs like <%= some_code %> indicates that something should be rendered. In this case, we can see that the “if else” logic of checking a user’s authentication does not need rendering, while the actual links to the Login/Logout functions need rendering, since they are actual buttons on the page.

The code that says something like link_to and new_user_session_path are just pre-built functions to make it more convenient (it also looks more readable, since it spells out exactly what it does). The Login line of code <%= link_to “Login”, new_user_session_path %> is essentially just an ‘a’ tag with the href value of /users/sign_in.

Logging in

When you login now, you should be able to see the Logout button, and the Sign in button would no longer be there. This allows users to see if they are logged in or out. Now if you ever want content that only users who are logged in should see, you know to just wrap it with these one of these lines: <% if user_signed_in? %> Yay, you are logged in!<% end %>

This is how the login page should look like now:

In the next article, we will go through Authorization, which means giving different users certain roles (such as Admin or Client) and allowing each of these roles to see different content.

Navigation

The next article can be found here. Previous article is here.