DEV Community

Joseph Louie
Joseph Louie

Posted on

How to create a Login and Logout with Devise

Finding about Devise

While learning Rails I was introduced to Bcrypt, which was a great intro to Authentication and Authorization. It reminded me of Sinatra. Why did it remind me of Sinatra you ask? Sinatra gives the user a couple of tools for you to use, but most of the time you will have to implement a lot of core code yourself. It's great primer to rails. Rails give you a lot of tools that just work. All you need to know is what it's suppose to do, it's input, it's output and your good to go. It abstracts a lot of what's under the hood for the user to help simplify their lives. Which is great!
Devise is similar to rails, where Devise hides a lot of what happens from the user. Devise has been around for 10 years now (2009 - 20019). It's still being actively maintained and is still the most popular option for authentication.

Why would you want to use Devise?

As mentioned above Devise does all the hard work for you when it comes to authentication. You get a whole suite of modules. To list some from there readme:

  • Database Authenticatable: hashes and stores a password in the database to validate the authenticity of a user while signing in.
  • Registerable: handles signing up users through a registration process, also allowing them to edit and destroy their account.
  • Validatable: provides validations of email and password.

There is so much more please feel free to look at what they offer in their Readme Devise Readme

Example of a simple app using Devise login and logout

To first implement devise we first need a app to play with. In this example I only have a User model.

First create a new app. I'll call my app devise-blog-post

rails new devise-blog-post
Enter fullscreen mode Exit fullscreen mode

Let Rails do it's thing.

Change into the newly created app

cd devise-blog-post/
Enter fullscreen mode Exit fullscreen mode

Open up your app in your text editor

code .
Enter fullscreen mode Exit fullscreen mode

Now comes the fun part

Let generate a User model with a name attribute.

rails g resource User name:string
Enter fullscreen mode Exit fullscreen mode

Migrate your database.

rails db:migrate
Enter fullscreen mode Exit fullscreen mode

You may need to reset your server if you encounter this error:

undefined method `devise_for' #<ActionDispatch::Routing::Mapper:0x000000042e1dd8>
Enter fullscreen mode Exit fullscreen mode

Lets create a view page so we have something to look at. With your app directory, you should see a views directory. Within the views directory, you should see users directory. Create a new file called index.html.erb. This file will be the first thing the user sees. We will make this file the root path. In my file:

<h1>Hi There!!</h1>
Enter fullscreen mode Exit fullscreen mode

Let add a line in the routes. In the config directory, you should see a routes file. Add:

root "users#index"
Enter fullscreen mode Exit fullscreen mode

We now need to bring Devise into our project.

  • In Gemfile add this code
gem "devise"
Enter fullscreen mode Exit fullscreen mode

In the terminal type

gem 'devise'
Enter fullscreen mode Exit fullscreen mode
bundle install
Enter fullscreen mode Exit fullscreen mode
rails generate devise:install
#you may need to stop spring which I had to do
# Type spring stop to stop spring
# then rails generate devise:install after stopping spring
Enter fullscreen mode Exit fullscreen mode

Devise lets you configure some settings
Alt Text

We want to generate Devise migration file, model, and add a line to routes
Alt Text

Next we migrate the newly created devise migration file. rails db:migrate is the same as rake db:migrate.
Alt Text

  • This step is probably optional for this small example, but it's one line of code so why not. Add after the line class UsersController < ApplicationController
before_action :authenticate_user!
Enter fullscreen mode Exit fullscreen mode

This line just says that a user has to be logged in to access a certain page. We could have added before_action :authenticate_user! to application_controller to require the user to be logged in to see all the pages, but this is a small example.

Lets also add a logout button to allow the user to logout.

# In index.html.erb in users dir
<%= button_to "logout", destroy_user_session_path, method: :delete  %>
Enter fullscreen mode Exit fullscreen mode

Where did destroy_user_session_path come from?? If we look at our routes. http://localhost:3000/rails/info/routes We can see that devise gives us routes!
Alt Text

Your files should looks like this.
Alt Text

Alt Text

Alt Text

If you go to http://localhost:3000/ it should redirect you to http://localhost:3000/users/sign_in
Alt Text

If you don't have an account sign up!
Alt Text

All this took me under 20mins which is really fast compared to a couple hours using Bcrypt. (Assuming you encounter bugs) This is only scraping the surface of what Devise can do! Go read the ReadMe for more.

Thank You for reading! If you have any suggestions or I did something incorrectly please leave a comment below and I'll try to address the issue.

Top comments (1)

Collapse
 
rahulmr profile image
Rahul Raut

Thanks for this tutorial , is it possible to store timestamp entries in database table when user performs sign in or sign out? Like last_sign_in_at and last_sign_out_at. Purpose is to calculate the first login and last logout of user. even calculate the overall time when user was logged in the application.