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.