#21
Apr 20, 2007

Super Simple Authentication

The final piece of the administration puzzle: authentication. There are many different approaches which is why I saved this step for last. This episode will cover a few techniques including the simple solution used for this site.
Download (24.7 MB, 6:41)
alternative download for iPod & Apple TV (11.8 MB, 6:41)
# controllers/application.rb
def admin?
  session[:password] == 'foobar'
end

# sessions_controller.rb
def create
  session[:password] = params[:password]
  flash[:notice] = "Successfully logged in"
  redirect_to home_path
end

def destroy
  reset_session
  flash[:notice] = "Successfully logged out"
  redirect_to login_path
end

# config/routes.rb
map.resources :sessions, :episodes
map.home '', :controller => 'episodes', :action => 'index'
map.login 'login', :controller => 'sessions', :action => 'new'
map.logout 'logout', :controller => 'sessions', :action => 'destroy'

RSS Feed for Episode Comments 46 comments

1. yari123 Apr 22, 2007 at 18:05

awesome job man! I regularly watch through all your railscasts when my memory needs some kick start. Your tutorials are THE BEST!


2. Bullwinkle The Moose Apr 22, 2007 at 20:53

Very useful. I'm with you from the very beginning. Great work!
Only thing: more tips and tricks, I think.


3. Jon Crawford Apr 23, 2007 at 10:17

Hey, man. Great work! Really helped me get going.

Is this the place to ask questions? I'm trying out acts_as_authenticated, and have hit one snag based on the helper method you wrote in the screencast. From what I can tell, current_user.name throws an error if the public tries to access the page without being logged in. I'm sure it's a simple fix, but I thought I'd point that out. And see if you had a quick solution.

!Jon


4. Piku Apr 23, 2007 at 10:34

Hey, super cool casts you make ;)
Can you make a screencast about using and integrating acts_as_auth or restfulauth ?


5. Ryan Bates Apr 23, 2007 at 11:33

@Jon,

Good question, I should have mentioned this in the screencast. You need to check if the user is logged in first:

def admin?
  logged_in? && current_user.admin?
end

Untested.


6. Lake Denman Apr 24, 2007 at 19:50

Fantastic Railscast. This was exactly what i needed.


7. Don Parish Apr 26, 2007 at 06:56

I wished I'd seen this before I installed acts_as_authenticated! I'll certainly use this for my next simple app!


8. Ryan Pittman May 03, 2007 at 19:21

Ryan, I was wondering if you could explain to me as to how the variables you are using such as 'home_path' and 'sessions_path' are set. Furthermore, I am trying to use these past 3 videos to create a simple auth system for a program I'm working on, but I can't seem to figure out 2 problems: 1 - how did you have your 'new.rhtml' load when you browsed to '/login', and 2 - how did you decide where to put the same file (I assumed it would be 'views\login'. I can explain more in detail if I can contact you via email, as I don't really want to make such a long comment on your website. Also if you or anybody on this site feel like they can help please do.

Finally, thank you for doing such a great favor to so many people by creating these wonderful screencasts.


9. Ryan Pittman May 03, 2007 at 19:26

Please disregard my previous post, as I forgot about the routing.rb file. I modified it according to your tutorial and it now works! Thanks again for such a great service!


10. James Whiteman May 26, 2007 at 18:36

Amazing work...this is _very_ timely for me. Thanks.


11. Brian Jun 24, 2007 at 20:54

Hi, i followed the tutorial and its great but i also try to enter any password and not use the foobar and it can pass.. how to resolve this? =)

on sessions_controller.rb
session[:username] = params[:username]

application.rb
session[:password] == "foobar"

Thanks dude! =)


12. Ryan Bates Jun 24, 2007 at 22:02

@Brian, although the message says "successfully logged in" when providing an incorrect password, the user will not have access to the administration capabilities unless the password matches. I did this for simplicity but it can be confusing so you may want to change it.

One way is to move the comparison further up. So instead of checking if the password matches in the "admin?" method, check it inside the "sessions/create" action. Then you can provide an error message when the password is incorrect.


13. Brian Jun 25, 2007 at 21:12

Can i ask for your help? =) because i have here is a project called "leaveform"

i want to have simple login system. i want to connect it to my users table.

and when they login, they can see the welcome screen.

here is my syntax in app/controllers/application.rb

# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
class ApplicationController < ActionController::Base
  # Pick a unique cookie name to distinguish our session data from others'

  session :session_key => '_leaveform_session_id'
  
  helper_method :admin?
  
  protected
  
  def authorize
    unless admin?
      flash[:error] = "Unauthorize access"
      redirect_to home_path
      false
    end
  end
  
  def admin?
  #create if statement here...
  if session [:password] == 'brian'
    true
    redirect_to home_path
    else
    false
    redirect_to error_path
  end
  end
 
end

here is the syntax of my app/controllers/sessions_controller.rb

class SessionsController < ApplicationController
  
  def create
    if session[:password] = params[:password]
    flash[:notice] = 'succesfully logged in'
    redirect_to home_path
    else
    redirect_to login_path
    end
  end
  
  def destroy
    reset_session
    flash[:notice] = 'successfully logged out'
    redirect_to login_path
  end
end


14. Brian Jun 25, 2007 at 22:10

@ryan bates

hi, i already fix my error.. sorry i didn't see the "==" in the password for the password is equals equals.

now its working and my next step is to connect ito database when i have users table.

Thanks =)


15. Brian Jun 26, 2007 at 23:49

Hi to all!,

any idea on how can i connect this one to database? Now, I have users table with username and password field in my users table. how do i connect this to the login system?

Thanks


16. Ryan Bates Jun 27, 2007 at 08:01

@Brian, I recommend asking your questions over at railsforum.com. That way it will be easier to post code samples and ask more detailed questions. I visit there frequently so hopefully I can get around to answering you there. Thanks.


17. Brian Jun 27, 2007 at 19:12

Thanks =)


18. Brian Jun 27, 2007 at 19:34

Hi,
I have posted it on:

    * Index
    * » Rails Programming
    * » Super Simple Authentication

Thanks


19. Kev Jul 05, 2007 at 11:17

Hi,

Really good screen casts but I am also having a problem with setting up the sessions_path and home_path variables

I have set up the the routes.rb file as specified in the video, but I get this error:

undefined method `first' for :sessions:Symbol

if i comment out the map.resources line
then I get the undefined method or variable sessions_path error.

Any help appreciated

Kev


20. Ryan Bates Jul 05, 2007 at 12:01

@Kev, what version of Rails are you using? This requires Rails 1.2. If you are using an older version then it won't work.


21. Kev Jul 06, 2007 at 02:12

@Ryan,

I thought that might have been the problem, so I upgraded - am now on 1.2 but the issue is still there.


22. Ofer Jul 14, 2007 at 12:40

Fixes to the source of routes.rb

1) should be map.logout for the logout line
2) probably should include:

  map.resources :sessions

Which may be @kev's problem.

Just discovered your series recently - still working my way throught them - they are very insightful even on the basic topics.


23. Ryan Bates Jul 14, 2007 at 13:52

@Ofer, thanks. Fixed.


24. Kev Jul 16, 2007 at 11:44

Hey guys,

been away from the code desk for a bit :)

When I upgraded rails to 1.2, should I have done anything to the app i.e. would it need to be ported?

I had already tried including:

map.resources :sessions in the routes.rb
file, but now the WEBrick won't finish booting up with the error:

undefined method `first' for :sessions:Symbol.

I'm a bit stuck and considering starting the site again using 1.2 as the starting point unless this sounds stupid.

Cheers


25. Ryan Bates Jul 16, 2007 at 13:10

@Kev, I use Rails 1.2 in these screencasts, so it should work without any problems. It's hard to tell what the issue is without seeing the code. You may want to post your question on railsforum.com along with your code.


26. Kev Jul 16, 2007 at 13:23

Btw, just fixed my issue - I didn't know that the environment.rb needed to be changed after an upgrade thanks for the help anyways


27. Tony V Aug 09, 2007 at 00:18

Really dumb question from a total noob, I'm sure: The routing action is shown as "new," but the action is shown in the SessionsController as "create." What am I not understanding?

BTW, Ryan, you totally rock.


28. Ryan Bates Aug 09, 2007 at 09:34

@Tony, the "new" action is really there, it's just not shown in the controller. There's a "new.rhtml" view which will be used for the new action. That just displays the login form. The "create" action handles the login process which is what the form goes to.


29. Tony V Aug 11, 2007 at 18:59

Got it. Ergo, the "create" action in the form. Thanks.


30. Jari Aug 17, 2007 at 03:19

I think you should never use IP based authentication, even if you're using only trusted addresses like 127.0.0.1, because it's possible to spoof the IP address:

http://www.securityfocus.com/infocus/1674

Also, if you're storing your password in a plain text form on a shared environment, make sure that only you have a read access to the file (chmod 600). Of course, encrypting your password is always encouraged.


31. Chris Oct 12, 2007 at 11:12

Is it possible to include the validation in the plugin with a dynamic validate method?


32. Ryan Bates Oct 12, 2007 at 15:04

@Chris, I'm not certain what you're asking. Which plugin are you referring to? And by validation do you mean the checking of the password?


33. Chris Oct 19, 2007 at 10:28

I'm sorry, I meant to post this on episode 33 making a plugin. In that episode, you ended with a validate method in the task.rb file and I was wondering if it were possible to include that in the plugin?


34. Chris Bloom Nov 28, 2007 at 08:54

Excellent 3-part series. I'm coming from a PHP background where I usually had a separate /admin folder, but I was stumped on the best way to do this RESTfully in Rails. This makes a lot of sense. I get it now, thanks to you!


35. tom n Dec 19, 2007 at 12:32

The naming confuses me. The session gets created automatically somehow by rails when a browser accepts a cookie or something? If you navigate to "new" I guess you get given a form text field that will call the create action that doesnt create a new session but sets the session[:password] . Is "create" a misnomer or am I missing something? Shouldn't it be called something like "set_password". The destroy seems to actually destroy all session information, not just the password so the naming seems appropriate.


36. Mieg Dec 23, 2007 at 16:14

hi,
can somebody tell me how the create action is called? in the screencast i just see a:

<% form_tag sessions_path do -%>

no mention of a create anywhere. I know how to fix this myself but i am just wondering how this works in the screencast without any mention of 'create' anywhere.

BTW i am a big fan of the railscasts, thanks!


37. cover Dec 25, 2007 at 01:57

@Mieg

He's using a REST way...
In the routes.rb he set map.resources :sessions
With this he can do a post request on sessions_path (or sessions_url) to do a create. With a delete request on an id session_url(id), :method => :delete call for a destroy and session_url(id), :method => :put is a call for update.
For more info have a look here http://api.rubyonrails.com/classes/ActionController/Resources.html


38. Ron Jan 16, 2008 at 02:01

Hi Ryan, excellent tutorial series. I was looking for a simple way to do an admin kit while keeping the code DRY. This method seems right up my alley, especially since I'm very new to Ruby and Rails. Thanks!


39. PJ Feb 28, 2008 at 11:53

I'm a little on the new side but I thought you were never supposed to store a password in the session? Isn't that a big security no-no?


40. Ryan Bates Feb 29, 2008 at 11:04

@PJ, good point. Honestly I haven't looked into the security risks. It's probably not the safest thing if the sessions are stored in the cookie as is the default with Rails 2. Alternatively you can do this:

session[:admin] = true

Which I believe will work okay.


41. Nate Mar 08, 2008 at 03:41

great tutorials man. I wanted to note quickly that when using restful_authentication you can add a simple administrator check by using your boolean in the user table method

and calling:

def admin?
   if logged in?
     current_user.admin?
   else
     false
   end
end

then create a new before filter

def admin_required
  admin? || access_denied
end

Thats a simple way to do it, but it allows you to filted certain actions by wether a user is an admin and other by just if they are loggedin or not.

I've hacked mine up a lot more but for simple sites I somethimes use this method.

Great screencasts man.


42. lauren Mar 10, 2008 at 16:28

Great episode -- this was really helpful.

RE PJ's security comment and Ryan's response: I was wondering exactly how that security risk would be fixed. What does the session[:admin] = true replace?


43. Nic May 08, 2008 at 05:23

Hi Ryan,

First of all, thanks for all your railscasts: wonderful job, helped me a lot !

I'm struggling on an authentication through LDAP, more specifically authenticating as Apple's Open Directory users...

any idea on how to do this ?


44. kino May 23, 2008 at 01:53

By means of analytic unity, the transcendental aesthetic has lying before it the thing in itself, and the architectonic of pure reason proves the validity of, so far as regards reason, our sense perceptions.


45. Ian Aug 06, 2008 at 16:39

Thanks for the screencast. You saved me a lot of time. You ROCK!!!


46. Stun Aug 07, 2008 at 17:52

Hi Ryan, I`m your big fan
Thanks for the screencast.

But I have a question. I think including password in session is danger isn`t it?

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player