How to create a Login and Logout with Devise
Tags: beginners, rails
Published: 2019-12-05 21:05:33

## 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](https://github.com/plataformatec/devise)

## 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
```

Let Rails do it's thing.

Change into the newly created app
```
cd devise-blog-post/
```

Open up your app in your text editor
```
code .
```

Now comes the fun part

Let generate a User model with a name attribute.
```
rails g resource User name:string
```

Migrate your database.
```
rails db:migrate
```
You may need to reset your server if you encounter this error:
```
undefined method `devise_for' #<ActionDispatch::Routing::Mapper:0x000000042e1dd8>
```

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>
```

Let add a line in the routes. In the config directory, you should see a routes file. Add:
```
root "users#index"
```

We now need to bring Devise into our project.
- In Gemfile add this code
```
gem "devise"
```
In the terminal type 
```
gem 'devise'
```
```
bundle install
```
```
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
```
Devise lets you configure some settings
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/v0lfi04bl8vnznjgt306.png)

We want to generate Devise migration file, model, and add a line to routes
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/vsyindk8pkilm4t83ml7.png)

Next we migrate the newly created devise migration file. rails db:migrate is the same as rake db:migrate.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/z6hikeqjnw2lxwto4xka.png)




- 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!
```
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  %>
```
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](https://thepracticaldev.s3.amazonaws.com/i/toj6cxce9lankrigzgij.png)

Your files should looks like this.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/tihigq5by2pk4pn5dity.png)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/u4wxvwwkkmzox4b06r0c.png)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/ncxlzo5am8upsad3hh0z.png)

If you go to http://localhost:3000/ it should redirect you to http://localhost:3000/users/sign_in
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/fqk8aqwgo0whh07clgjh.png)

If you don't have an account sign up!
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/0scldu2n4m7oixk7dwh2.png)

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.