A very simple login example with Rails

This is just a little step by step on how to create a simple login with Rails, of course you can use a plugin to do it for you, but this way you can understand what the plugin is doing.

Let’s start creating a new Rails application:

$rails applicationName

Then we create a controller with a view for the login:

$script/generate controller login login

The code for the login_controller.rb will be the following:

class LoginController < ApplicationController
def index
render :action => 'login'
end
def login
end
def do_login
username = params[:username]
password = params[:password]
if username.nil? || password.nil? || username==password
redirect_to :action => "login"
flash[:notice] = 'Unknown user or invalid password'
else
session["user_id"] = username
redirect_to :controller => "secure", :action => "index"
end
end
end

Basically the controller has to implement only the do_login method, this is the one that will authenticate the user, in this example it only validates if the user filled the username and password fields, but later you can search the database for it.

The login view will have the following code:

<% form_tag :action => 'do_login' do %>
<table class="loginForm" align="center"><tbody>
<tr>
<td>Login</td>
<td><input name="username" type="text" /></td>
</tr>
<tr>
<td>Password</td>
<td><input name="password" type="password" /></td>
</tr>
<tr>
<td colspan="2"><%= submit_tag "Login" %></td>
</tr>
</tbody></table>
<table><% end %>

It is a simple view, with only two fields and since we do not have a user model I did not used the rails form helpers …

Ok, perfect until now, but how do I use it?

let’s change the application.rb file, the code will be the following:

class ApplicationController < ActionController::Base
# Pick a unique cookie name to distinguish our session data from others'
session :session_key => '_untitled6_session_id'
before_filter :authorize
protected
# Override in controller classes that should require authentication
def secure?
false
end
private
def authorize
if secure? &amp;&amp; session["user_id"].nil?
session["return_to"] = request.request_uri
redirect_to :controller => "login", :action => "login"
return false
end
end
end

The code above adds a before filter to every method of every controller in your application (since all controllers extends ApplicationController), this method will intercept the calls and if the controller is “secure” and the user did not authenticated yet, the user will be redirected to the login page, otherwise the filter will do nothing. To secure a controller you just need to override the “secure?” method and return true.

Now let’s create a simple controller that will need authentication …

$script/generate controller secure index

This line above creates a new controller with only an index action.

Now let’s edit the secure_controller.rb file

class SegureController < ApplicationController
def index
end
protected
def secure?
true
end
end

Overriding the “secure?” method to return true we tell the application that all actions in this controller need authentication.

But if we and only a few actions to need authentication? Than we can use some thing like the code bellow!

protected
def secure?
["secureMethod","anotherSecureMethod"].include?(action_name)
end

This way only the “secureMethod” and the “anotherSecureMethod” will need authentication.

Every thing ready, now we have a login implemented in a rails application …

Try starting the server (ruby script/server from the application’s directory) and access http://localhost:3000/secure and you will see the login screen instead of the index.rhtml contents.

Of course we can improve this example in many ways, for example:

  • in the method do_login we can use the session[”return_to”] to redirect the user to the first requested page.
  • We can create a users/groups structure and implement the authorization using that

And you, how would you improve the example above?

Do you see any problem in this example?

If you enjoyed this post, make sure you subscribe to my RSS feed!

6 comments so far

  1. Jeremy Weiskotten October 15, 2007 2:36 pm

    The LoginController doesn’t need the empty login action method. The template will be rendered without it.

    Although, I’d suggest moving do_login into login, and wrapping it with an if request.post?, having the form post to that action (remember that forms post to the rendered action by default, so you wouldn’t have to specify an :action on the form).

    Otherwise, consider a more RESTful approach — it looks like SessionController with #create (for login) and #destroy (for logout) actions is in vogue at the moment.

  2. Urubatan October 15, 2007 5:59 pm

    Thanks for the comments Jeremy,
    I’ll write another example using your tips :D
    about the “login” and “do_login” method, I prefer this way because I need one less “if” in the code :D

  3. Zachary Fox October 16, 2007 4:13 pm

    I agree with Jeremy. I’d rather have less methods in my controller than one less if statement. I’m just getting started with the RESTful stuff, and I’m not 100% sold on it yet, but I like the idea of a session controller.

    Thank you for creating a simple example and explaining it. Obviously, for real access control, you need to go a couple of steps further. Maybe you could show us that next.

  4. […] A very simple login example with Rails | Urubatan’s Weblog (tags: rails rubyonrails authentication login example ruby ror webdev web development programming) […]

  5. Urubatan October 17, 2007 9:02 am

    Zachary, I liked the idea, I´ll improve the example with a little of REST and with some Authorization too (this one, the main purpose id the authentication only :D )
    And will write another post about it, probably next week.
    Thanks for commenting.

  6. […] Recent Comments Notebook para que? PortableApps.com! | Blog do Urubatan on Why do you need a laptop? Try PortableApps.comJos Hirth on Use your mobile phone to control your presentations with Open OfficeUrubatan on Recording screencasts with Linux (Ubuntu/Kubuntu)Tom on Recording screencasts with Linux (Ubuntu/Kubuntu)Urubatan on A very simple login example with Rails […]

Leave a comment

Please be polite and on topic. Your e-mail will never be published.