Articles

Creating a Login System in Rails

Introduction

Continuing to build our Ruby on Rails driven site, our Employee Information System has been created. Now we just don't want anyone to come and access it. We would like to add levels of abstraction which means only the privileged users can come and see the database, once they login to the system.

Now what should be the flow of the system

Chart showing program flow
Figure 1

As the user comes to the Landing Page, he is presented with a Login Form. The fields are Username, Password and Go. If the user enters a correct set of credentials, he is taken to the employee index page where the list of employees is displayed and the user can add a new set of employees.

Let's start by first adding a table in the database. Let' s name it, users table as it holds all the records of System Users. We create a Model for this so that we have the tables and we can write some logic for our users.

 

  saurabh@home:/media/S3A6128D005/Users/ongc/eim$ ruby script/generate model user
exists  app/models/
exists  test/unit/
exists  test/fixtures/
create  app/models/user.rb
create  test/unit/user_test.rb
create  test/fixtures/users.yml
exists  db/migrate
create  db/migrate/20091116113942_create_users.rb
Edit the migration file to add table details to it:
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column :username,                     :string
t.column :password,          :string, :limit => 40
t.column :salt,                      :string, :limit => 40
t.timestamps
end
end
def self.down
drop_table :users
end
end

We will encrypt our password before storing into the database as a measure of security. To do our encryption we will use the rub digest library which creates a an MD5 encrypted password and a salt, which works as a key to decrypt the password.

 

  saurabh@home:/media/S3A6128D005/Users/ongc/eim$ rake db:migrate
(in /media/S3A6128D005/Users/ongc/eim)
==  CreateUsers: migrating =====================================
-- create_table(:users)
-> 0.0856s
==  CreateUsers: migrated (0.0858s) ============================

In our model, we add validations to check if the username is unique or not and whether the password is present or not. The encrypt password method in the model generates an MD5 encryption and password matching

 

  
require "digest"
class User < ActiveRecord::Base
validates_uniqueness_of :user
validates_presence_of :user, :password
def encrypt_password
if (self.salt == nil)
self.salt = salt_generator(5)
self.password = Digest::MD5.hexdigest(self.salt + self.password)
else
self.password = Digest::MD5.hexdigest(salt + self.password)
end
end
def password_matches?(password_to_match)
self.password == Digest::MD5.hexdigest(self.salt + password_to_match)
end
private
def salt_generator(len)
numbers = ("0".."9").to_a
newrand = ""
1.upto(len) { |i| newrand << numbers[rand(numbers.size - 1)] }
return newrand
end
end

Now, we start creating the controller to add the login and logout actions to it. We will also add an access level such that login is made compulsory to the system for entering any employee record.

 

    def login
if request.post? and params[:user]
@User = User.new(params[:user])
user = User.find_by_username(@User.username)
if user and user.password_matches?(@User.password)
session[:id] = user.id
redirect_to :action => 'index'
else
flash[:notice] = "Invalid Username or Password!"
end
end
end
def logout
if session[:id]
reset_session
redirect_to :action => 'login'
end    
end

In this method, the Login action calls the user details using the parameter username, it matches the username and password with the entered credentials; starts the session with a user id being carried in it and redirects the action to index. Logout action calls the session id and calls reset_session method, which destroys a session.

Once, we have finished creating a login and logout we need to make it a compulsion to login before a user can access an employee's details. The before_filter directive helps to put to force this rule onto all the people who access the system.

 

    before_filter :login_required, :except => [:login, :logout]
private 
def login_required    
if !session[:id]
redirect_to "/admin/login"
return false
end    
end

With controller, Model and the database ready, we can now go ahead and create our Login Page view, login.htmlerb.

 

  <% form_for :user, @user do |f| %>
<%= error_messages_for :user %>
Username: <%= f.text_field :username %>
Password: <%= f.password_field :password %>
<%= submit_tag "Go" %>
   <% end %>

Our login system is now ready to use.

Plugin Methods to Implement Login in Rails

Now a days there are a lot of plugins available which saves a lot of time and effort. Below you'll find some more of the popular ones thatwork with Ruby on Rails.

 

  1. Restful Authentication: Previously known as acts_as_authenticated, Restful authenticated is a full blown login system plugin which generates the signup flow along with login, the restful way. It also contains a system for activation email and key. It can be downloaded at http://github.com/technoweenie/restful- authentication.
  2. Authlogic: Another very popular and clean implementation of Rails based Login system is Authlogic. It generates the users and sessions for the application and simply resides inside the vendors/plugins folder. It can be downloaded at http:// github.com/binarylogic/authlogic.
  3. Muck-Users: Muck and autlogic gem based system, which generates, Login, Sessions and User Creation Logic. It can be used by downloading from http:// github.com/binarylogic/authlogic.

Conclusion

Rails provides multiple methods of encryption like sha1 and MD5 internally as a part of the Rails framework. However, the plugins provide a fairly simple and straightforward methods to implement login, sessions and sign up flow.

 

 Original article


Website Design | Website Development | Flash animation | Flex applications | Logo Design | Mobile Applications Development | iPhone | iPad | Google Android

Content Management Systems | E-Commerce | Social Networking | Dating Websites | Membership Websites | Zend Framework | PRADO | Symfony | Wordpress

ASP.NET | PHP | C# | Objective-C | AJAX | Web 2.0 | HTML | CSS | Javascript | MySQL | MSSQL

 


Host unlimited domains + get up to 5 FREE domains with your 1&1 hosting account. Must see monthly hosting specials!


Invite your friends to Stable Flow

Enter up to 3 email addresses of your friends: