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.