Creating authentication from scratch in Rails 3.1

There are some popular authentication libraries like devise, Authlogic, Restful Authentication, Clearance in Ruby on Rails. But, you can implement of your own as well.

Here, I’m explaining few simple steps to create your own authentication system in Rails 3.1. First, Create Run following commands from command prompt and then copy the codes in the respective files:

Create new rails application

rails new rails3-auth-from-scratch

Generate user model/controller/views

rails g scaffold user first_name:string last_name:string email:string password_digest:string

Migrate database to create users table

rake db:migrate

Generate sessions controller

rails g controller sessions new

Modify user model by following codes in app/models/user.rb

class User < ActiveRecord::Base
attr_accessible :email, :first_name, :last_name, :password_digest
has_secure_password

def name
"#{first_name} #{last_name}"
end

def self.authenticate(email, password)
find_by_email(email).try(:authenticate, password)
end
end

Add bcrypt-ruby gem in to Gemfile to encrypt password and run bundle install

gem 'bcrypt-ruby'

Write/Copy following codes in app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
protect_from_forgery

def authenticate!
if !logged_in?
redirect_to login_url, :alert => "You must login to access that page."
end
end

private

def logged_in?
return true if current_user.present?
end

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

helper_method :current_user, :logged_in?
end

Authentication codes in app/controllers/sessions_controller.rb

class SessionsController < ApplicationController
def new
end

def create
# if the user is found and the user's password authenticates
if user = User.authenticate(params[:email], params[:password])
create_user_session(user)
else
flash.now.notice = "Invalid email or password"
render "new"
end
end

def destroy
reset_session
redirect_to root_url, :notice => "Logged out!"
end

private
def create_user_session(user)
session[:email] = user.email
session[:user_id] = user.id
redirect_to root_url, :notice => "Logged in!"
end
end

Copy code snippet for login widget in app/views/sessions/new.html.erb

<%= form_tag sessions_path do %>

<%= label_tag :email %>


<%= text_field_tag :email %>



<%= label_tag :password %>


<%= password_field_tag :password %>



<%= submit_tag 'Login', :class => 'btn' %>

<% end %>

Update resources and path information in app/models/user.rb

resources :users
resources :sessions, :only => [:new, :create, :destroy]

get 'logout' => 'sessions#destroy', :as => 'logout'
get 'login' => 'sessions#new', :as => 'login'
get 'signup' => 'users#new', :as => 'signup'
post 'sessions' => 'sessions#create'

root :to => 'users#index'

Now, Run the application and go to “users/new” to create first user. After creating the user add following line at top of app/controllers/users-controller.rb to filter authenticated users:

before_filter :authenticate!

That’s it. Now you refresh the browser and see the full functional authentication system.

Click here to checkout the full functional application with user management.

Leave a Comment