[Ruby On Rails] Authentication – has_secure_password Feature (3) – Signin/Signout

This is the third part of the “has_secure_password” Feature in Rails. This post explains how to signin or signout to/from your application. Please read the previous posts (Overview and Signup).

1. Add Controller

Authentication is managed with “Session“. So you need a controller to handle this.

> rails g controller Sessions

 

2. Configure Routes

In the “config/routes.rb” file, add the following code.

resources :sessions, only: [:new, :create, :destroy]

match '/signin',  to: 'sessions#new',         via: 'get'
match '/signout', to: 'sessions#destroy',     via: 'delete'

 

3. Add Actions

The “User” model provides “authenticate” method. By creating or deleting a session, you can practically login or logout a user.

class SessionsController < ApplicationController
  def new
  end

  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      session[:user_id] = user.id
      flash[:success] = "Successfully Logged in"
      redirect_to user
    else
      flash.now[:warning] = "Invalid email or password"
      render "new"
    end
  end

  def destroy
    session[:user_id] = nil
    flash[:info] = "Logged out!"
    redirect_to root_url
  end
end

 

4. Login form

Add the “new.html.erb” file to the “views/sessions” folder.

</pre>
<h2>Sign in</h2>
<div class="row">
  <div>
  <%= form_for(:session, url: sessions_path, html: { class: "form-horizontal" }) do |f| %>

    <div class="form-group">
      <%= f.label :email, class: "col-sm-2 control-label" %>
      <div class="col-sm-6"><%= f.text_field :email %></div>
    </div>
    <div class="form-group">
      <%= f.label :password, class: "col-sm-2 control-label" %>
      <div class="col-sm-6"><%= f.password_field :password %></div>
    </div>
    <div class="form-group">
      <div class="col-sm-offset-2 col-sm-6"><%= f.submit "Sign In", class: "btn btn-large btn-primary" %></div>
    </div>
  <% end %>
  </div>
</div>
<div class="row">
  <p>New user? <%= link_to "Sign up now!", new_user_path %></p>
</div>

 

5. Helpers

In the “helpers/sessions_helper.rb” file, add the following methods.

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

  def signed_in?
    !current_user.nil?
  end
end

To make this helper methods available in all controllers, add the following code to the “controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  include SessionsHelper
end

 

6. Signin/Signout Link

You can create a link using the helper method.

<% if signed_in? %>
  <li><%= link_to current_user.name, current_user %></li>
  <li><%= link_to "Sign Out", signout_path, method: :delete %></li>
<% else %>
  <li><%= link_to "Sign In", new_session_path %></li>
<% end %>

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s