Devise is a flexible authentication solution for Rails, it supports to common functionality such as: create new account, sign in, sign up, reset password ...
It’s composed of 10 modules:
Database Authenticatable: hashes and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication.
A migration to create User table: YYYYMMDDHHMMSS_devise_create_users.rb
User model: app/models/user.rb
Add routes for user and test files.
Open User model (app/models/user.rb), you can see default devise modules:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatableend
For this demo, we use additional 2 modules:
confirmable – Users will have to confirm their e-mails after registration before being allowed to sign in.
trackable - tracks sign in count, timestamps and IP address.
Tips: I use awesome_print gem to view that on rails console
Configure Devise
Initialize devise: config/initializers/devise.rb
Devise.setup do |config|
[ ...]
# ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class
# with default "from" parameter.
config.mailer_sender = '[email protected]'
[...] # More setting
end
Set up the default URL options for the Devise Mailer
In development environment: (config/environments/development.rb)
In production environment, host should be set to the actual host of your application.
You should restart your application after changing Devise’s configuration options (this includes stopping spring). Otherwise, you will run into strange errors, for example, users being unable to login and route helpers being undefined.
Usage Devise for Authentication
Devise supports some helpers to use inside your controllers and views.
To verify if a user is signed in, use the helper:
user_signed_in?
For the current signed-in user, use this helper:
current_user
Add Sign_up/ Log_in / Log_out links
You can add HTML code below to your view header of application:
destroy_user_session_path: Log out path, method :delete is default HTTP method used to sign out a User
new_user_session_path: Log in path.
new_user_registration_path: Create new user path
Sign Up: Create a new User account by click to Sign_up link, you'll see the view like that:
Sign up form
Flow Sign up:
Enter email, password and password confirmation => Click to Sign up button
User'll receive a confirmation email.
Click to confirmation link to verify the account.
Done, ready to Log in.
To read the confirmation email easy, I recommend installing a gem, called Letter Opener - which help we preview email in the default browser instead of sending it.
Install letter_opener gem:
Add the gem to your development environment and run the bundle command to install it.
group :development do
[...]gem 'letter_opener'end
Then set the delivery method in config/environments/development.rb
Restart server! and start to create a new User account.
An example of a confirmation-instruction-email on browser after using letter_opener:
Confirmation instruction Email
Log in: Click to Log_in link, you’ll see the form like that:
Log in form
Authentication for Post
We want to add the authentication functions for managing Posts (CRUD Post) for User. That means, only signed-in users are who can manage Posts.
To set up user authentication for a controller, just add this before_action:
before_action :authenticate_user!
class PostsController < ApplicationController
[...]
before_action :authenticate_user!
[...]
end
When user NOT sign-in yet, and click to 'Manage Posts', the application auto-redirect user to the Log-in page. You can view log in the console like this:
Started GET "/posts" for ::1 at 2020-MM-DD 13:37:35 +0700
Processing by PostsController#index as HTML
Completed 401 Unauthorized in 2ms (ActiveRecord: 0.0ms | Allocations: 349)
Now, to manage CRUD Posts, you have to already signed in to system.
Add Post Details page
Create Blog controller with show action:
rails generate controller Blogs show
Output logs:
Running via Spring preloader in process 23109
create app/controllers/blogs_controller.rb
route get 'blogs/show'
invoke erb
create app/views/blogs
create app/views/blogs/show.html.erb
invoke test_unit
create test/controllers/blogs_controller_test.rb
invoke helper
create app/helpers/blogs_helper.rb
invoke test_unit
invoke assets
invoke scss
create app/assets/stylesheets/blogs.scss
Update Rails routes: (/blogs/:id)
Rails.application.routes.draw do
[...]resources :blogs, only: [:show]
end
Import trix_editor.scss and blogs.scss to application.scss (import at the bottom of file)
[...]
@import "trix_editor";
@import "blogs";
Yey done!
Conclusion
In this article, I already guide you about the Devise gem and how to use Devise to add authentication functions as create a new User account, Login, Logout in Rails application. Beside, I help you step by step add the Post details page to Blog application.