Jeff Kreeftmeijer

Simple authentication with Warden

2010-04-13

There are a lot of Ruby authentication libraries out there, which can do about everything like sending confirmation emails and resetting passwords. I didn’t really want that. My plan was to write a little application that could authenticate using Github credentials (more on Github authentication in “Authenticating via Github with Guestlist”).

This meant I didn’t need email confirmations, password reset functionality or even registration. Also, I didn’t want to log in using an email address and password or check my own database to see if the user exists. So, no Authlogic or Clearance for me. I had to go find a more low-level solution.

It didn’t take long before I found Warden, a “General Rack Authentication Framework”.

Warden, General Rack Authentication Framework

“Warden is rack based middleware, designed to provide a mechanism for authentication in Ruby web applications. It is a common mechanism that fits into the Rack Machinery to offer powerful options for authentication.”

Remember: it does not do registration, confirmation and the like. If you want anything like that, use Devise, a Rails authentication system based on Warden. @rbates also did a great Railscast on Devise.

“Warden uses the concept of cascading strategies to determine if a request should be authenticated. Warden will try strategies one after another until either one succeeds, no Strategies are found relevant or a strategy fails.”

An example of a strategy would be a user logging in with his username and password:

Warden::Strategies.add(:my_strategy) do
  
  def valid?
    params[:username] && params[:password]
  end

  def authenticate!
    u = User.find_by_username_and_password(
      params[:username],
      params[:password] # you should encrypt this. ;)
    )
    
    u.nil? ? fail!("Couldn't log in") : success!(u)
  end
end

The valid? method checks if the strategy is valid. In the example above it will return false when the username and password aren’t both in the params. In that case it will fail without even having to try and find the user.

authenticate! calls fail! with a message when the authentication failed. If the authentication passes, it’ll pass the User instance to success!. Pretty simple.

I’m not going into any specific stuff here, but if you’re using Rails you might want to check out rails_warden_mongoid_example. It’s a pretty simple and understandable application that shows you how to use Warden. Also, be sure to read the wiki, it has pretty good setup and example pages and there’s a lot more cool stuff in there.