OpenID Authentication in Rails (Part 2)
In my last post about integrating OpenID with Rails, we took a look at using the ruby-openid gem and also the open_id_authentication plugin to add the ability for users to log in to a website using their OpenID rather than a username and password. But what about when a user is creating a new account, and wants to use their OpenID?
A Couple of Options
First of all, there are a couple of options when it comes to account creation. If you remember from the last post, when someone wants to use an OpenID to log in, we simply bypassed the usual log in process for our Rails app (in this case I am using restful_authentication). However, creating a new account presents some difficulties, and there are some options for getting around them.
The best way to describe this is to talk through it. A user comes to the website that they want to create an account at, and is presented with a create your account form. The user can select whether or not to use a username/password combination, or to use OpenID for logging in to the account they are creating. Seems easy enough. From there, they submit the form and the account is created as normal. Nothing new here. Or is there? If we are using the username field as a key, or have it displayed on our website, we need to be aware that there will be no username value associated with a user that has created an account with OpenID. Additionally, we will need to adjust any model validations that we have in place for the username field. For example, we will want to change any validations like this:
validates_presence_of :username
to something more like this:
validates_presence_of :username, :if => :using_username?
Which will make our validation of the username field conditional on whether or not the method using_username? is true. That method might look something like:
def using_username?
not self.username.blank?
end
Although this is a simple example and the real validation should probably be a little more complex. The point being that we need to be aware that the username field will be blank.
One option for getting around this, such as if you want to display every account holders username on the site, is to require the username and just leave out the password. That way you are storing the username (which is just a display name) and the OpenID.
Unified Profiles
However, in many cases there is a user profile associated with an OpenID, which gives another option for creating accounts. With this, you have a choice to offer. One option is to check the profile that someone has provided with their OpenID and comparing it to the values set when the user submitted the form. If there are conflicting values for anything (such as username being different from the OpenID nickname), and the user would be prompted to reconcile those differences.
Another option is to have the user select a either a username/password combination or to use and OpenID right at the beginning. That way the next screen that they reach is a profile screen that, if the person opted to use an OpenID, the values that could be extracted from their OpenID profile and applied to the profile form are already filled in.
A third option is to just ignore the OpenID profile all together, and just honor the OpenID for log in purposes.
A Quick Note
As a quick note, I have recently stopped using the restful_authentication plugin available for Rails in preference of using the Authlogic gem, which I find to be easier to use and offers more features that I want to use. However, there is a great tutorial on integrating OpenID with Authlogic authentication available.
This post is filed under Developers' Corner and has the following keyword tags: ruby, rails, OpenID, open_id_authentication.