In my previous post, I showed you how to easily create a simple signup for your Rails app, without needing any external gems. In that post, I showed you how to build a signup form and let the Rails built-in feature of
has_secure_password handle account registration and password hashing.
In this post, I'll show you how to let users log in and authenticate them by using the methods that
has_secure_password automatically adds to your User-type model.
The Account model
First of all, let's take a look at my user-type model. In my app samentweeten.nl, it is called
Account. This is what it looks like:
class Account < ApplicationRecord has_secure_password validates :email, presence: true, uniqueness: true end
has_secure_password your model needs the
password_digest database field. The
password_digest field will contain the hashed and encrypted password. Here's the migration for my
class CreateAccounts < ActiveRecord::Migration[5.0] def change create_table :accounts do |t| t.string :email t.string :password_digest t.timestamps end end end
The previous code is all we need to use Rails' built-in
has_secure_password functionality on the model and database end. Let's look at the controller and our login form in the next section.
Creating the login form and authenticating the user
For logging in the account, I'm using a
SessionsController to handle all the sign in logic. This controller has a
destroy method to show the login form, authenticate the user and logs it back out.
Here's my login form:
Here's the code for my
class SessionsController < ApplicationController def new # render the login form end def create @account = Account.find_by("LOWER(email) = ?", account_params[:email].downcase) if @account.present? && @account.authenticate(account_params[:password]) cookies.permanent.signed[:account_id] = @account.id redirect_to dashboard_url else render :new end end def destroy cookies.delete(:account_id) redirect_to root_url end private def account_params params.require(:account).permit(:email, :password) end end
The login form POSTs a form with an email address and a password to the
#create method of my controller. In the
#create method, the following happens:
- Fetch the account record that belongs to the given email address from
account_params[:email]and put it into
- Check if we found a record using
if @account.present?and authenticate it with the given password using
- If all is good, we store the account records id in a permanent signed cookie with
cookies.permanent.signed[:account_id] = @account.idand redirect the user to their dashboard.
Done! The above is all you need for a simple login in your Rails app using the
authenticate() method that you get for free when using
has_secure_password on your user-type model.
Let's take a quick look at how to destroy the user session.
To destroy the user session, we can point a "Logout" link or button somewhere in the user interface to the
#destroy method on my
SessionsController and execute the following code:
class SessionsController < ApplicationController # new and create methods here def destroy cookies.delete(:account_id) redirect_to root_url end end
#destroy method clears the
account_id cookie and redirects to the frontpage of my app.