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.
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
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
Open up your app in your text editor
Now comes the fun part
Let generate a User model with a name attribute.
rails g resource User name:string
Migrate your database.
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:
Let add a line in the routes. In the config directory, you should see a routes file. Add:
We now need to bring Devise into our project.
- In Gemfile add this code
In the terminal type
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
- 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
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!
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.