The buzz about OpenID keeps building, and with the announcement that all AOL/AIM users now automatically have OpenIDs it doesn’t look set to slow down any time soon. For those who’re not familiar with the concept, OpenID is a distributed single sign-on system that lets you set up one account and then log in to any OpenID compliant site using that account. For a better introduction, check out this screencast from Simon Willison.
There’s already been a fair bit of work done to allow ruby and rails apps to make use of open ID. There’s a gem, ported from the python library which provides APis for consumers and servers. And there’s a rails plugin that provides some generators for creating the models and controllers you need to interact with the gem.
I’ve been playing with the plugin on and off for a couple of months, but yesterday finally got round to integrating it properly with an application that I’ve been gradually developing. The app uses restful_authentication to handle its login needs, and I had to make a few customizations to get everything working as I want.
The process I adopted was to say that people can either create a standard account with a regular username and password, or they can sign in with their OpenID and then create an account in my system that will be authenticated against that OpenID. So the first step was simply to adapt the sign up form to include some explanation, and an OpenID sign in form.
I then had to update the controller that the plugin had created for me. By default it responds to a successful Open ID sign in by presenting a user with a page presenting the details of their Open ID identity, but I wanted to take it a step further.
I replaced the default code in the controller with:
when OpenID::SUCCESS
user = User.find_by_openid_url(open_id_response.identity_url)
if user.nil?
session[:openid] = open_id_response.identity_url
flash[:attributes] = open_id_fields
flash[:notice] = 'Thank you, we have confirmed your identity. Please proceed to create your account'
redirect_to new_user_url and return
else
self.current_user = user
flash[:notice] = 'Thank you. You are now logged in'
redirect_to "/" and return
end
That checks whether there’s already an account for that open id. If there is, we consider the user logged in and take them to the homepage. If not, we store their openid details in the session and send them to complete the sign up.
By also adding:
params[:user][:openid_url] = session[:openid] if session[:openid]
in UsersController#create and making a few simple changes to the default User model supplied with restful_authentication so that it doesn’t require a login/password when it has an OpenID, I have an app which can take full advantage of OpenID, and my users have one less set of login details to remember.
Given the popularity of acts_as_authenticated and restful_authentication, it would be good to see a plugin which does all the work of integrating OpenID with those libraries. It shouldn’t be much work; if time allows, I may have a go, but if anyone beats me to it please let me know!