Topic: RoR 2.0.2 :: Very simple authentication from scratch in 15 steps
RoR 2.0.2 :: Very simple authentication from scratch in 15 steps
1.- rails pm -d mysql [ Creating a rails project called pm ]
2.- cd pm [ Change directory to the pm directory ]
3.- Edit your config/database.yml with your db user/password [ No explanation required ]
4.- rake db:create:all
[ This will create 3 databases: pm_development,pm_test,pm_production
* Nice thing would be to see a message of the result of what is doing perhaps in future releases ]
5.- ruby script\generate scaffold project title:string description:text [ Create files & migration files for a projects table with the fields title & description - yes timestamp will be by default included ]
6.- ruby script\generate controller sessions login logout [ This controller will take care of the authentication ]
7.- lets run our migration...
rake db:migrate
c:\ruby\railapps\pm>rake db:migrate
(in c:/ruby/railapps/pm)
== 1 CreateProjects: migrating ================================================
-- create_table(:projects)
-> 0.0940s
== 1 CreateProjects: migrated (0.0940s) =======================================
8.- Let's secure the Index Projects page for the New Project:
#app/views/projects/index.html.erb
Replace:
<td><%= link_to 'Show', project %></td>
<td><%= link_to 'Edit', edit_project_path(project) %></td>
<td><%= link_to 'Destroy', project, :confirm => 'Are you sure?', :method => :delete %></td>
With:
<td><%= link_to 'Show', project %></td><% if admin? %>
<td><%= link_to 'Edit', edit_project_path(project) %></td>
<td><%= link_to 'Destroy', project, :confirm => 'Are you sure?', :method => :delete %></td>
<% end %>
...
at the end of the file apply for the new project:
...
<% if admin? %>
<%= link_to 'New project', new_project_path %>
<% end %>
[ This will only show the Edit and Destroy links if admin? is true ]
9.- Lets declare this important admin? method in the Application Controller to make it accessible for all the models.
#app/controller/application.rb
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
Add the following code:
helper_method :admin?protected
def authorize
unless admin?
flash[:error] = "unauthorized access"
redirect_to home_path
false
end
enddef admin?
session[:password] == 'railsforum'
end
[ A couple questions will raise here...
the first part helper_method :admin? make the admin? method available on the view.
the second part will default the password to 'railsforum' not the best practice this is just for learning purposes. perhaps phase 2 will be to encrypt this password or retrieve from a DB Table.
the third part for the authorize method will check for the validation of the admin? object and redirect to home_path (this does not exist yet but will be ;-) please be patient... ) in case of failure.
10.- In the projects controller file add a before_filter method to perform the authorize validation previously declared
#app/controller/projects_controller.rb
class ProjectsController < ApplicationController
# GET /projects
To:
class ProjectsController < ApplicationController
before_filter :authorize, :except => :index# GET /projects....
11.- Lets create 2 methods on the sessions controller to perform the authentication:
#app/controller/sessions_controller.rb
class SessionsController < ApplicationControllerdef login
enddef logout
end
end
Change to:
class SessionsController < ApplicationControllerdef create
session[:password] = params[:password]
flash[:notice] = "Successfully logged in"
redirect_to home_path
enddef destroy
reset_session
flash[:notice] = "Successfully logged out"
redirect_to login_path
endend
12.- In order to permit our application to access the login / logout pages lets add to the routes...
#config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.resources :projects
Change to:
ActionController::Routing::Routes.draw do |map|
map.resources :projects, :sessions
map.home '', :controller => 'projects', :action => 'index'
map.login 'login', :controller => 'sessions', :action => 'new'
map.logout 'logout', :controller => 'sessions', :action => 'destroy'
This will add the :sessions controller to the resources.
Also provide a default index page (yes we still need to delete the default index page public/index.html)
With the map.login give us the url path /login or /logout and route it to the sessions controller using the appropiate action.
13.- Remove the default index.html file located at: public/index.html
14.- The last thing to do is to create the content of the /login page. [This particular trick took me a little bit to understand since is just on the view. Create a file called 'new.html.erb' just like the action described on the routes file, since we created all this on the begining just rename the file called login.html.erb to new.html.eb.
#mv app/views/sessions/login.html.erb app/views/sessions/new.html.erb
Edit the file and enter the form for the Login:
<h1>Sessions#login</h1>
<p>Find me in app/views/sessions/login.html.erb</p>
change to:
<center>
<% form_tag sessions_path do %>
Password <%= password_field_tag :password %>
<% end %>
</center>
[ This is the simple login form used to authenticate ]
#app/views/sessions/logout.html.erb
<h1>Sessions#logout</h1>
<p>Find me in app/views/sessions/logout.html.erb</p>
Change to:
<center>
<h3> Successfully Logout </h3>
</center>
15.- Everything is ready let's launch the web server
script\server
To start will show:
Listing projects
Title Description
At this point there is no projects in the application.
Let's login:
http://127.0.0.1:3000/login
As password enter "railsforum" then hit enter... feel free to play with your projects application.
Once your are ready to leave the site go to:
http://127.0.0.1:3000/logout
Yes I know a link will be more appropiate but feel free to tweak your needs.
That's All, I hope you enjoy and learn something else today, yes there are many other ways to do it, this is just a particular solution for a very small scale requirements, but surely fits my needs ;-)
I want to thank Ryan Bates for his great work on www.railscasts.com - This tutorial is inspired in his awesome work on the videos 20-21-22. I never could learn as much about rails in a short period of time without the help & inspiration of his screencasts.. yes yes... some books, peepcode, and a lot online research...
Features:
Provide security to a RoR application with a very simple controller.
More learning about the methods in the view & the smart usage of routes.
To learn more about how everything works behind the scenes not just plugin usage ;-)
Todo:
Enable the keep an MD5 of the password instead of plain text.
Combine with previous application with Permalinks: http://www.railsforum.com/viewtopic.php?id=14236 and setup a more complete application with authentication.
Enable a little bit more complex authentication with user/password/groups... to allow small teams to interact in a very simple way without the complexity of another table on the DB.
It's that time of the year and I will enjoy the SuperBowl from Toluca, Mexico, go Rails Go, yes Go Patriots GO!!!
Din00z.
Last edited by dinooz (2008-03-03 13:55:54)