Authentication from Scratch : Login and Logout

Objective


To implement Login and Logout features.

Steps


Step 1

Create a sessions controller.

rails g controller sessions new

Step 2

Add:

resources :sessions

in routes.rb and delete :

get 'sessions/new'

Step 3

Create app/views/sessions/new.html.erb:

<h1>Log In</h1>

<%= form_tag sessions_path do %>
  <div class="field">
          <%= label_tag :email %><br />
          <%= text_field_tag :email, params[:email] %>
  </div>
  <div class="field">
          <%= label_tag :password %><br />
          <%= password_field_tag :password %>
  </div>
  <div class="actions"><%= submit_tag "Log In" %>
<% end %>

Step 4

In sessions_controller.rb, implement the create action:

  def create
    user = User.find_by_email(params[:email])
    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      redirect_to root_url, notice: "Logged in!"
    else
      flash.now.alert = "Email or password is invalid."
    end
  end

This authenticates the user and if the user enters the right credentials, it will login the user.

Step 5

Add the login link to the application layout, application.html.erb:

  <%= link_to "Log In", new_session_path %>

Add the code to display the flash messages in the layout file:

<% flash.each do |name, msg| %>
    <%= content_tag :div, msg, class: "alert alert-info" %>
<% end %>

The application.html.erb file now looks like this:

<body>

<%= link_to "Sign Up", new_user_path %>
<%= link_to "Log In", new_session_path %>

  <% flash.each do |name, msg| %>
     <%= content_tag :div, msg, class: "alert alert-info" %>
  <% end %>

<%= yield %>

</body>

Step 6

Reload the home page. Click 'Log In' and use the new user credentials to login.

Step 7

Change the application controller as follows:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  private

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end

  helper_method :current_user
end

Now we can use the current_user helper in the view.

Step 8

In application.html.erb, use the helper defined to display the links:

<% if current_user %>
  Logged in as <%= current_user.email %>.
<% else %>
  <%= link_to "Sign Up", new_user_path %> or
  <%= link_to "Log In", new_session_path %>
<% end %>

Reload the home page to see the email of the logged in user.

Step 9

In sessions_controller, add destroy action:

def destroy
  session[:user_id] = nil
  redirect_to root_url, notice: 'Logged out!'
end

Step 10

Add:

<%= link_to "Log Out", session_path("current"), method: "delete" %> 

to application.html.erb. Reload page. Click logout to logout.

Step 11

To implement automatic login on registration, add:

session[:user_id] = @user.id

to users_controller.rb like this:

def create
  @user = User.new(permitted_params)
  if @user.save
    session[:user_id] = @user.id
    redirect_to root_url, notice: "Thank you for signing up!"
  else
    render "new"
  end
end

Now the user will be automatically logged in when they register for an account.

Summary


In this article, we implemented login, logout and automatic login on registration features. In the next article we will continue to develop more features related to user management.


Related Articles


Create your own user feedback survey