#82
Dec 02, 2007

HTTP Basic Authentication

Rails 2.0 offers an extremely easy way to do HTTP basic authentication. See how in this episode.
Download (11.6 MB, 4:23)
alternative download for iPod & Apple TV (6.6 MB, 4:23)

Resources

# products_controller.rb
before_filter :authenticate

protected

def authenticate
  authenticate_or_request_with_http_basic do |username, password|
    username == "foo" && password == "bar"
  end
end

RSS Feed for Episode Comments 37 comments

1. August Lilleaas Dec 03, 2007 at 03:43

Oh, hey, that's neat. Was just googling for this. Should make REST-authentication super easy, and then using the usernames and passwords in the database to authenticate.

<pre>
authenticate_or_request_with_httpt_basic do |username, password|
  User.authenticate(username, password)
end
</pre>

Wohoo!


2. nelson jr Dec 03, 2007 at 14:22

Hi. Sorry my stupid question, but how can I do logout using http_basic? :-)

Bye


3. Ryan Bates Dec 03, 2007 at 20:48

@August, right! Since the authentication is handled in a block there's a lot of flexibility. Moving it to the user model (if you have one) is a good idea.

@nelson, that's a good question. The authentication is kept in the browser (client side), so there's really no way to log out the user on the server side AFAIK. The user will have to close the browser to end the session. I think there are hacks around this issue, but I haven't looked into them.


4. Joel Leibow Dec 03, 2007 at 22:57

I have a really stupid question. What is that Growl type notification that pops up whenever you are executing keyboard shortcuts in Textmate? That could be handy for me if I could figure out what it is and how to get it.


5. August Lilleaas Dec 03, 2007 at 23:24

@Joel: Yeah, that was a stupid question =P It's listed on the "about" page, and is called KeyCastr.

@nelson: As Ryan says, http based authentication doesn't support logout. But as we're rails developers, we should be used to using systems that's opinionated and that makes choices for us - which is exactly what http does. This kind of authentication is rarely used to authenticate users through browsers, but it's ideal for authenticating in API's and so on, as most API reading systems supports the HTTP standards.


6. nelson jr Dec 04, 2007 at 10:13

@August, @Ryan: then using Model inside the 'authenticate_or_request_with_http_basic' as used on the example, I have support to logout? The authenticate don't will stay registered on client-side?

(srry my english guys)

[]s :)


7. August Lilleaas Dec 05, 2007 at 02:17

@nelson jr: As opposed to the "normal" way of authenticating, where you set session[:user] to something (which is what e.g. the restful_authentication does), this particular method authenticates you if the stuff inside the block returns true. So, doing this would authenticate you:

authenticate_or_request_with_http_basic { true }

This is what a User.authenticate action could look like:

def self.authenticate(username, password)
  user = self.find_by_username(username)
  user && user.valid_password?(password)
end

This method returns true if a user was found and the password was valid. Otherwise, it returns false (if the password wasn't valid) or nil (if no user was found with the specified username).


8. Scott Barr Dec 05, 2007 at 05:07

@August Lilleaas

You are absolutely right. To elaborate a bit more for nelson jr, with HTTP Basic Authentication and REST you won't need to use a server-side session at all. The server authenticates you and services your request. You then cease to exist to the server, as you are not actually "logged in".

This makes running a service/site across a cluster or servers simple because your session state (logged in, not logged in etc) isn't of any concern. A subsequent request could go to any server in a cluster and it wouldn't be a problem because you provide your authentication details again.


9. Ryan Dec 08, 2007 at 20:12

I would imagine you could still create a session for the user, right?

Also, how would this work for HTTP Digest Authentication? Could you do this with OpenID instead of a Username/Password combination?


10. Patrick Dec 09, 2007 at 12:55

Hello,

I just want to say "thank you". I'm new to rails and I like it. Your screencasts are great. I don't understand each of them fully, but from day to day I understand more.

Bye,
 Patrick


11. Ryan Bates Dec 11, 2007 at 10:34

@Ryan, I don't see what benefit storing it in a session would give because the browser will usually store the login credentials on its own. If you store it in a session it will be in two different places which could get messy.

As for HTTP Digest Authentication, I don't think Rails 2.0 offers an easy way to do this. But I haven't looked into it.

Also, I don't see any way to incorporate OpenID authentication into this.


12. Joe Dec 12, 2007 at 08:47

I'm currently using restful_authentication. So, in the move to Rails 2.0, should I stick with that and "enhance" it with this? Based on August's comments, that is what is implied. Where might the code August posted be put? Sorry, my newby-ness is apparent.


13. Chris Dec 21, 2007 at 06:38

Do you know if its possible to use http to request information from the user other than login credentials?


14. Win Dec 25, 2007 at 19:30

Keep up the great work guys! As I continue my education with rails (and ruby) into the 2.0 transition, your railscasts are a breath of fresh air in the often dark tunnel I call rails newbieness of which I suffer greatly.


15. rolando Jan 02, 2008 at 22:55

@ryan
How would one do the call to such an authenticated controller from activeresource. How does one pass the request authentification at the reqest time. does that go into the model or is that a step done during the find?

I mean like so:
*model*
class Event < ActiveResource::Base
   self.site ="http://localhost:3000/"
end

*irb*
s=Event.find 989


16. Coop Jan 20, 2008 at 03:40

I haven't seen it asked yet and I've done some google-ing and haven't come up with a result either...

I want a authenticated? / logged_in? method. Because in my views I want the edit | delete links visible for the authenticated user but obviously not the general public...

Does anyone have any ideas? Thanks in advance.


17. Joshua White Feb 10, 2008 at 15:43

I set up the auth model you described and it worked great. I switched my site to using it in development no problem. Then I went live, which is mongrel w/apache cgi. I can't seem to get the username and password through to rails. Has anyone found a good way to do this. I've gone through a lot of tutorials and guessing with no luck.


18. Oskar Lissheim-Boethius Mar 11, 2008 at 16:05

http_basic only works when running through curl with http://user@pass:localhost:3000/etc, not when running in Safari or Camino--I never get a window to enter the credentials, it just passes through, and then obviously creates the dreaded "nil" error when the @user can't be authenticated and found.


19. Eilert Islaksen Mar 30, 2008 at 15:32

@Coop, no idea how to but I'm wondering the same thing.


20. Coop Apr 05, 2008 at 18:24

@Eilert Islaksen, I don't think that it's possible otherwise someone would have said something...

@Oskar Lissheim-Boethius, I use Safari and always get the HTTP box to input my details


21. Benjamin Quorning Apr 11, 2008 at 01:17

@Coop, Eilert Islaksen: I too was wondering how to combine authenticate_or_request_with_http_basic with the show/hide edit/delete links explained in Railscast 20.

The way I achieved this was to set an is_authenticated instance variable:

# products_controller.rb
def authenticate
  @is_authenticated = authenticate_or_request_with_http_basic do |username, password|
    username == "foo" && password == "bar"
  end
end

Then you can show/hide in the view by:

# index.haml
- if @is_authenticated
  = link_to …

You could add a helper method:

# application.rb
helper_method :admin?
def admin?
  @is_authenticated
end

and go:

# index.haml
- if admin?
  = link_to …


22. kino May 23, 2008 at 01:08

Do you know if its possible to use http to request information from the user other than login credentials?


23. Mark Jun 15, 2008 at 13:07

@kino: it is possible, check it in manual.


24. Joshua Jul 16, 2008 at 01:08

If you're having troubles with getting HTTP Basic Authentication working with Apache fcgi try adding this to your htaccess file.

RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]


25. ruby developer Jul 20, 2008 at 07:14

Очень простой и понятный пример. Спасибо!


26. Jasper Aug 12, 2008 at 06:18

@nelson et al.

A way (hack) to logout of HTTP-Basic-auth is to let the user follow a link to a special 'logout' resource which will always return "401 Unauthorized", after which the browser will reset the user's credentials and therefore stop sending them as such.


27. Pete Aug 14, 2008 at 21:34

@Joshua - Just what I needed, thanks!


28. QQ Aug 14, 2008 at 23:18

@Benjamin Quorning:
HI,your "admin?" helper method does't work,why?thanks


29. Martin Sep 09, 2008 at 14:44

In finding out how to password the exception_logger interface, I came across this neat stuff:

http://errtheblog.com/posts/67-evil-twin-plugin

Here's my code:

http://gist.github.com/9771

and that's that.

Hope it helps someone.


30. Benjamin Quorning Sep 26, 2008 at 23:02

@QQ

Yeah, sorry, my code example didn’t work. I ended up using the session object to get it working: http://pastie.org/280240


31. Anthony Ettinger Sep 28, 2008 at 13:06

How would I add this to my demo and test environments?

I want basic authentication based on environemt


32. fiesta money Nov 20, 2008 at 17:35

Thanks Ryan,I think this is one of the most wonderful sites. I have great admiration for you.


33. 2moons gold Nov 21, 2008 at 18:31

I have great admiration for you.


34. lily Nov 27, 2008 at 18:38

Thank you Ryan, your screencast is good. Please look at our URL, I believe you will not disappoint.


35. evden eve nakliyat Dec 01, 2008 at 00:50

evden eve nakliyat


36. Minichamps Dec 02, 2008 at 06:59

I just want to say "thank you". I'm new to rails and I like it. Your screencasts are great. I don't understand each of them fully, but from day to day I understand more.


37. eve online isk Dec 04, 2008 at 01:31

I just want to say thank you! It is so wonderful! I have admiration for you!

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