Dr Nic

Sample Rails app: multi-OpenIDs per user

Last time, on “Dr Nic loves OpenID”…

Dr Nic had watched a video by Simon Willison glorifying the delights of OpenID to some Googlers.

Dr Nic decided that each User might like to link multiple OpenIDs to their application account.

Of course, if a user wanted multiple accounts then they could use their different OpenIDs to do that too.

All Dr Nic had to do now, was write some code…

OpenId logo

In the mean-whilst…

Later that very same day, Dr Nic reads a tutorial by Joseph Smarr at PlaxoA Recipe for OpenID-Enabling Your Site. He is joyed that Joseph had said the same thing:

It’s a many-to-one relationship (each user can have multiple OpenIDs attached to their account,
but a given OpenID can only be claimed by a single user)

“Champion!” Exclaims Dr Nic in the seclusion of his underground lair 300m isolated tower kitchen.

This article also lays out an implementation plan. It is in excruciating detail, including table schemas, stylesheet snippets and form suggestions.

Dr Nic rubbed his hands together and gets busy…

[/end of 3rd person]

Sample app

As a developer, the only reason you wouldn’t want to support “multiple OpenIDs per User” is because it is a PITA to implement, in that its an administrative bonus feature for your app. Its not really adding any real uber value.

So I followed his instructions – more or less – an have created a sample app. The README includes a demonstration of the app. You can also download it as a ZIP or TAR bundle.

User account with multiple OpenIDs

Now you can add multiple OpenIDs per user and be lazy at the same time.

The app builds on top of Ben Curtis’ OpenID sample app, and uses a variation of Ryan Bates’ Railscasts theme, because its sexy.

NOTE: The code is built for Rails Edge, but the two bundles do not include rails edge, so you need to rake rails:freeze:edge after unpacking it (all this and more in the README). If you want to work with Rails 1.2.3 gems, then.. um, I didn’t write a list of changes, but it might still work, I haven’t tested it. Ben’s original app was built for 1.2.3, so at its very heart it should still work. Perhaps.

Deviations from the Joesph’s tutorial

I want my users to be able to throw their OpenID around on any old page where they see an OpenID field.

That is, allow users to login or register with OpenID from either the “login” form or the “registration/signup” form. Within Rails, these are traditionally two separate controllers (sessions and users respectively).

So, I extracted out this functionality in to a module (helper user_openids_helper) and its used by the two controllers.

How’s it work?

Same way that Ben’s sample app worked, more or less, so read his article a couple times, then read through the source code for the multi-OpenID sample app.

I guess a couple tourist highlights might be:

  • app/helpers/user_openids_helper.rb – the extract fancy code
  • config/routes.rb – we need more routes to support alternate callbacks from OpenID providers
  • sessions_controller.rb and users_controller.rb – they are emptier and cleaner now
  • test\functionals\sessions_controller.rb – at the bottom are some test cases for the login/registration features of user_openids_helper

So, grab your Code Camera…

Related posts:

  1. Instant new Rails applications with the App Scrolls When I start a new project I want to start...
  2. Using CoffeeScript in Rails and even on Heroku I’m pretty excited about CoffeeScript as a clean-syntax replacement for...
  3. First look at rails 3.0.pre This article is out of date in some aspects....
  4. Rails themes can remember things I was getting annoyed at having to remember all the...
  5. Install any HTML theme/template into your Rails app Have you ever even bothered to Google for “rails...

24 Responses to “Sample Rails app: multi-OpenIDs per user”

  1. matt says:

    Thanks. Your post was quite apropos as I’m implementing this today. Mostly, though, I just wanted to add a comment using your OpenId widget down here to make sure things work as expect … *grin*

  2. Dr Nic says:

    @matt [via] – my mum would call that “talking just to hear the sound of your own voice”. So to speak… :)

  3. JoNtE says:

    Yet another splendid, yet wicked article. Thanks Nic.
    OpenId will be enabled on my next site, promise ;)
    // JoNtE, IGoRuby participant,

  4. Jared says:

    The only thing I’m not entirely clear on is WHY a user would want to associate multiple OpenIDs with a single account.

    For example, let’s say I have an OpenID identity for sites I visit from home on my own time, and a separate OpenID identity for sites I visit at work, on business time. I probably wouldn’t be mixing and matching site visits between identities. Are there real-world cases where someone has multiple identity URIs and uses them to visit the same site?

  5. avocade says:

    @jared: what if you have tied your openid to your own domain (mydomain.com, using LinkRel) and then forget to renew it? (Stupid, but it could happen. Plan for the worst, I say.) Or if your OpenID-provider gets shoddy and you want to ditch it for another one?

    Multiple OpenID’s for one account is a Good Thing(tm).

  6. Jared says:

    @avocade [via] – In both cases, my hypothetical site supports editing your profile once signed in, so if you changed OpenID providers, you could change the identity url stored in connection with your profile. I’m just not really seeing a use case where you’d need to interchangeably use multiple OpenIDs per account.

    I know it’s hard to gauge intent over the Internet, so let me state that I’m not being contrary just for the sake of it, I genuinely am curious if there’s a benefit that I’m just not seeing.

  7. Dr Nic says:

    @Jared [via] – I think more and more data and services will be supported by OpenID providers in time. Accessing and aggregating this data into an application might be desirable – different OpenID providers might allow you/automatically support different data/services. For certain there is already a draft specification for “Attribute Exchange” to allow an OpenID provider to send permissible data to applications if it changes.

    As you say, perhaps having just one OpenID per application is preferable and logical. Certainly it is easier to support.

  8. This is cool. Very cool. Infact I liked it so much I paid asked Nic to implement on the new amazing App that he has been building for us for almost a year! (Sorry Nic, the Hype has got to start somewhere – might as well be your site) ;-)

  9. Leevi Graham says:

    Hey Dr Nic, Thanks for the sample app.

    I have followed the instructions but hit a wall.

    When trying to start the server i get the following error:

    /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/servers/mongrel.rb:15: warning: already initialized constant OPTIONS
    /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/servers/mongrel.rb:18: undefined method `options’ for []:Array (NoMethodError)

    Im using edge rails: REVISION_7263
    Gem: gemsonrails-0.7.0 (not sure if his matters)

    Running Ben Curtis’s app works fine.

    Any ideas?

  10. Leevi Graham says:

    OK sorted this one out.

    The solution for me was installing the ruby-debug gem – sudo gem install ruby-debug

    The reason: /config/environments/development.rb requires it.

    begin
    require ‘ruby-debug’
    rescue
    config.breakpoint_server = true
    end

  11. MattK says:

    Thanks Dr. Nic for the sample app!
    And thanks leevi for the pointer. I like the idea that a user can claim any openid that they can authenticate. After all, I might have multiples that contain different info about me.

  12. grebo says:

    You might want to fix the tab order on this comment widget. If you tab from the OpenID Identity field, it goes to the Search box.

  13. generic zagam online…

    Here’s an overview of online pharmacies…

  14. [...] Dr Nic :: Sample Rails app: multi-OpenIDs per user [...]

  15. ryw says:

    I’m curious how many people have multiple openid’s at present

  16. [...] ** Dr. Nic Williams for his multiple-openids-per-user-sample-app which I used as a starting point for the REZM sample app which I’ll put up soon. [...]

  17. g7obs says:

    Excellent Post, this saves me hacking this for my own site

  18. face says:

    Thanks Dr. Nick! This is a perfect start.

    I just ported your sample app to rails 2.0.2 before I integrate it into my project. Here is my notes and your ported code available to all: http://myutil.com/2007/12/29/openid-2-0-2-with-rails-2-0-2

    Thanks again.

  19. Dr Nic says:

    @face [via] – thx for the updated code. I will leave your blog article as the source for the latest tarball of the starter code. Thx again.

  20. face says:

    Hello Again,

    I found a unexpected feature. The example adds edit, update, and destroy to users_controller.rb via params[:id]. This allows anyone logged in to edit, update, and destroy any registered user of the system (by changing the URI). To fix, simply change the first line of edit, update, and destroy in users_controller.rb to find the current logged in user and ignore the URI (i.e. @user = User.find(self.current_user.id)).

    Thanks again for the great OpenID example.

  21. code crumbs says:

    [...] found face’s port of Dr. Nic’s sample open_id_authentication app to be a useful starting point. I ended up chopping down the open_id_helpers class to [...]

  22. [...] — 撰寫的參考文件; * OpenID Authentication çš„ Readme 以及 * Dr.nic Sample Rails app: multi-OpenIDs per user [...]

  23. [...] back, Dr. Nic Williams wrote about allowing multiple OpenIDs per user in your Rails apps, and even put forward a nice little Rails example app on that topic. For Rails [...]

  24. [...] Ben Cutis 修改, 增加了可以讓使用者直接用 openID 建立新的帳號。 後來被 Dr. Nic 修改, 增加了一個使用者, 多個 openID 的功能。 Dr. Nic [...]