This article has no code in it. There are no TODO steps. Nothing to install. Its a picture of the future.
There is no reason to bookmark this article and read it another day. Its nearly all pictures. You can read it now.
This “picture of the future” was actually added to our browsers in the 90s. Netscape and MSIE3.0 both had it.
“It” is Client Certificates, and to me to means “never logging on with username/password NOR OpenID ever again”. Zero Sign On. It must be better than the much-targetted Single Sign On.
Client Certificates
Firefox 2.0:
Or on Safari/KeyChain:
Small problem: no website I’ve ever used has ever offered them, so I never knew they existed. I didn’t know what they did, nor as a web developer that I could create them for users who’d never need to login again.
Clifford Heath showed me the light. On #roro irc channel, we were exploring how “Zero Sign On” might be implemented using ssh-keygen, and browser plugins etc. Clifford mentioned client certificates and then someone else mentioned that MyOpenID already supported them. [someone = Michael Kedzierski]
I already had an myopenid account, so raced over to explore the new world of certificates.
Under “Authentication Settings”:
After submit:
And then:
Then feedback:
So I thought to test out if “Zero Sign On” actually worked. Normally, after logging out you’d need to submit username/password or if a site supported OpenID (yes myopenid.com is an OpenID provider which is a bit circular but bear with me) you login by entering your OpenID url and pressing Enter. Either way, you’ve got work to do.
Instead, I clicked “Login” link on the home page, and was redirected immediately to:
So it was still using cookies so that it could log me in immediately next time without clicking “login”, but either way, there is no username/password nor any other “type something here” login form. Just a “Remember Me” checkbox.
Finally, myopenid.com shows a log of your sign-in attempts:
Your sites and the future
As a web developer, you can do one of two things to get some leverage of Client Certificates.
Support OpenID as a login mechanism. Users with myopenid.com accounts (or other openid providers that support client certificates) will benefit from automatic login to their openid page and instant redirection to your site. You’ll also be able to help new users import their profile data to get them started quickly.
Implement Client Certificates yourself. I would have liked to have had a crack at this before posting about Client Certificates and all their sweet loveliness, but I didn’t. My bad. Instead, I found a nice step-by-step (plus comments with updates) on implementing Client Certificates
If you have/do implement Client Certificates in Ruby/Rails world, you’ll get a 1000 Happy Points from me if you open source it/blog about it. Happy Points are redeemable for Happiness in all countries.
Web apps/services go down for maintenance (expected or erroneously) all the time.
What happens when your “sign on to all apps everywhere” OpenID server goes down for an hour? You might not be able to login to any site.
Your users may not be able to log into YOUR app.
MyOpenID is going down on the 12th of September (see below) for an hour.
Allowing them to login with multipleOpenIDs might alleviate any difficulty users have using/buying your stuff.
Even if they have clicked “Allow Forever”, and it appears that they never revisit their OpenID provider again when logging into your site, they actually still do via the wonders of HTTP redirection, and those zippy quick InterTubes we take for granted.
Supporting multiple OpenIDs in your app isn’t much more effort than supporting one OpenID. You just need an extra table and a form for creating them.
The Plaxo article on multiple OpenIDs per user kind of makes it all appear a bit daunting, IMO.
But with the sweet Ruby OpenID gem and starting points like Ben Curtis sample app or my multiple-openid sample app, it might take only a 1/2 day or a day to educate yourself about OpenID, and hack it in to one of your apps.
Say, like your blog. Please.
This is a notice that MyOpenID will be having a maintenance
outage starting at 08:00 on 2007/09/12, Pacific Time.
The outage may last as long as 60 minutes, but is expected
to be considerably shorter.
The reason for this outage is:
Database upgrade
During the outage, the MyOpenID website may be unavailable or
unresponsive, and users will be unable log into OpenID-enabled
websites using their MyOpenID accounts. The latest information about
this and other MyOpenID events can always be found on http://janrain.com/blog/
We apologize for the inconvenience. If you have any questions, please
contact us at support@myopenid.com.
Voting starts Wednesday. I’ve viewed a dozen or so front pages, and they all look awesome. But to useany a lot of them (I think) you need to create an account.
Unfortunately there are only 10 that used OpenID. (see pastie for code)
So for the other 136, you must now create usernames and accounts. Type your email and password 136 times.
Linga is a hypertext meta-universe in which we can all cavort and play. Through the power of teh intertubes, and the the little truck-like links betwixt them, we provide c…
The joglog is a simple, motivating running log. It provides good feedback on your training, allowing you to track dates, times, distances and many other parameters.
You may login as test:test to see real running data.
Nourish allows users to create and track well designed, RSS driven newsletters. Publishers can mash-up more than one feed, specify timed delivery, and customize the email templates to make simple RSS-driven newsletters.
Send your fish swimming through the waters of your favorite social network, or the internet at large! Don’t like what your fish finds? Tweak it’s genetic code!
Writing tool that helps you write research papers. Lets you outline and structure your thoughts, then fill in the text. Keeps track of bibliographic information and helps to format everything properly at the end. Something like Scrivener, but hosted…
Note: if your site is using OpenID but my script didn’t pick it, let me know below and I’ll add it.
Having suggested that OpenID is the answer to the 146 signups that are required for 146 applications, I actually think I’d be even cooler for RailsRumble (or any other competition) to have a single-signon mechanism, that once you signup, it tells all 146 apps to create you an account and log you in. THAT would be useful.
$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_posts&field=post_title&limit=5&order=post_title"
[{"attributes": {"post_title": "OpenID count"}},
{"attributes": {"post_title": "MagicCGI shows OpenID user count"}},
{"attributes": {"post_title": "map_by_method now works with ActiveRecord associations"}},
{"attributes": {"post_title": "Feedburner"}},
{"attributes": {"post_title": "One year on the InterTubes"}}
]
Oh oh oh, how about a list of comments for a specific user?
$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_comments&user_id=1"
...comments by Dr Nic...
or
$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_comments&user_id=1&action=count"
232
Dr Nic’s commented in his own blog 232 times? Out of how many comments?
#!/usr/local/bin/ruby
require 'magic_cgi' # loads the render magic, model magic, and meta-model magic
include Render
require 'magic_cgi/config/wordpress' # connect to DB using Wordpress installation (wp-config.php)
MagicCGI::Config::Wordpress.establish_connection "/path/to/drnicwilliams/web/public"
# The following is defaulted for Wordpress connections:
MagicCGI::Config.hidden_tables |= %w[wp_openid_nonces wp_openid_associations wp_usermeta wp_tla_rss_map wp_tla_data]
MagicCGI::Config.hidden_columns['wp_users'] = %w[user_email user_pass user_activation_key]
MagicCGI::Config.hidden_columns['wp_openid_identities'] = %w[hash]
MagicCGI::Config.hidden_columns['wp_comments'] = %w[comment_author_email comment_author_IP]
MagicCGI::Config.hidden_columns['wp_posts'] = %w[post_password]
render do |params|
data = DbTable.from_params(params)
data ||= begin
table_name = params['table'].first || 'wp_users'
model_name = ActiveRecord::Base.class_name(table_name)
klass = MagicCGI::MagicModel.create_class(model_name, ActiveRecord::Base)
klass.find_or_count_by_params(params)
end
data
end
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 lair300m 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.
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