Authentication with Ruby on Rails 4.2

02.02.2015 by Stefan Wintermeyer

Thumbnail of the video.

This screencast shows how to add a simple password authentication for your Ruby on Rails 4.2 application without using the big shots like Devise or OmniAuth (see for a list of popular authentication gems).

Create the Rails application

We start with a fresh Ruby on Rails application.

rails new shop
cd shop

For the has_secure_password method we need the bcrypt gem. And because we don’t need a JSON API in this application deactivate the jbuilder gem.


# Build JSON APIs with ease. Read more:
# gem 'jbuilder', '~> 2.0'
# Use ActiveModel has_secure_password
gem 'bcrypt', '~> 3.1.7'

After saving the Gemfile we need to run bundle.


Generate a Root Page

As a start we create a Page controller with an index view:

rails g controller Page index

We use that view as the root_path:


Rails.application.routes.draw do
  get 'page/index'
  root 'page#index'

We start the rails development server:

rails s

Fire up the browser and open

Generate a User scaffold

We use a User model to store the user information and the password digest. We do not store the password in clear text in the database.

rails g scaffold User first_name last_name email password:digest
rake db:migrate

In the User model we add a couple of validations and a to_s method.


class User < ActiveRecord::Base
  validates :first_name,
            presence: true
  validates :last_name,
            presence: true
  validates :email,
            presence: true,
            uniqueness: true,
            format: {
              with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
  def to_s
    "#{first_name} #{last_name}"

Create a new user

We create the User “Jon Smith” with

Create a Session controller

Having a User model is nice but we need a Session mechanism to create a login and logout procedure. Because we live in a RESTful world login would be new plus create and logout would be destroy in a Sessions controller.

rails g controller sessions new create destroy

Now we create a couple of routes for this to work:


Rails.application.routes.draw do
  resources :sessions, only: [:new, :create, :destroy]
  get 'signup', to: 'users#new', as: 'signup'
  get 'login', to: 'sessions#new', as: 'login'
  get 'logout', to: 'sessions#destroy', as: 'logout'
  resources :users
  get 'page/index'
  root 'page#index'

Login Form

The login form is the new.html.erb view for a new Session.


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

Session Controller

The Session controller needs 3 actions:

With that we use the RESTful approach.


class SessionsController < ApplicationController
  def new
  def create
    user = User.find_by_email(params[:email])
    if user && user.authenticate(params[:password])
      session[:user_id] =
      redirect_to root_url, notice: 'Logged in!'
      render :new
  def destroy
    session[:user_id] = nil
    redirect_to root_url, notice: 'Logged out!'

Create a current_user method

We need a mechanism to access the current_user everywhere in the application. For that we add a current_user method to the ApplicationController and use helper_method to provide a helper method for the views too.


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
  def current_user
    User.where(id: session[:user_id]).first
  helper_method :current_user

To show a user if he/she is already logged in and if not where to login or where to sign up we add a little header HTML in application.html.erb

Additionally I add some code to show flash messages if there are any.


<div id="user_header">
  <% if current_user %>
    Logged in as <%= %>.
    <%= link_to "Log Out", logout_path %>
  <% else %>
    <%= link_to "Sign Up", signup_path %> or
    <%= link_to "Log In", login_path %>
  <% end %>
<% flash.each do |key, value| %>
  <%= content_tag(:div, class: "alert alert-#{key}") do %>
    <p><%= value %></p>
  <% end %>
<% end %>

Because we render the flash messages in application.html.erb we can delete them in the following files:

<p id="notice"><%= notice %></p>

Auto login when a new user signs up

When ever a new user signs up it makes sense for him to be logged in right away. That’s easy done by setting the session session[:user_id] = in the users_controller.rb.


  # POST /users
  def create
    @user =
      session[:user_id] =
      redirect_to root_url, notice: 'User was successfully created.'
      render :new

Next step

In the next screencast I’ll show how to use this authentication to setup an authorization system which grands or denies access to specific users.

Rails Ruby Authentication