It’s just data

OpenID for non-SuperUsers

Based on the results of my Unobtrusive OpenID post, it is quite evident that there is a lot of partial knowledge about OpenID out there.  While my knowledge on the subject is far from complete, this post is my attempt to share what I have learned with others.

The target audience for the bulk of this post is people who are capable of adding autodiscovery links to their blog templates, may be able to install a small PHP script and/or know what a HTTP header is.

Claim Your Blog

For starters, one thing I didn’t make clear is that I was expecting people to continue to use their blog or homepage URI’s; what I did not expect was that people would start to use their identity URIs instead.  These people have identities hosted by LiveJournal, Verisign, MyOpenID, 2idi, Technorati, Vox, TypeKey, and others.

What I expected would happen instead is that people would claim their blogs using their identity.  In OpenID terms, this is called delegation, which sounds scary, but in reality it is just a form of autodiscovery, just like you do for your feed.

If you have an OpenID identity and a blog, then follow these instructions.  If you don’t have an OpenID identity, you can get one for free at MyOpenIDHere’s mine.

Given such an identity, copy the following into the head section of your weblog, adjusting the two URIs as appropriate:

<link rel="openid.server" href="" />
<link rel="openid.delegate" href="" />

That’s pretty much it.  What this says is that the web page in question is owned by the owner of and furthermore may be used to verify ownership of

By claiming your blog or homepage in this fashion, you can then use your URI (i.e., the URI of your blog or homepage) as your identity.  Having this level of indirection is a good thing.  If you ever become dissatisfied with your identity provider for whatever reason, you can easily and transparently switch providers.

When done, feel free to check your setup.  You may find that the autodiscovery features of most OpenID libraries are not as robust as those for feed autodiscovery.  Never fear, there is a solution for this later in this post.

Master Of Your Domain

This next step is entirely unnecessary, but I suspect that it will be popular with many of the readers of this blog.  Letting someone else host your identity is actually good from a security perspective, after all, any fool can vouch for themselves (and below, I’ll show you how), but having somebody else vouch for you is often better, if for no other reason, it gives the person who is checking up on you a place to report spammers.

Of course, services can be compromised; but as already stated, you can always switch providers quickly.

The real downside is privacy.  It gives somebody else partial information about a portion of your online habits.  And much of the information that they don’t have is readily discoverable.

There is also control issues.  After all, what good is a decentralized identity system where your only real choice is to delegate to a centralized server that you don’t control?

The good news is that it is easy.  You don’t need any of these libraries.  Simply download phpMyID.  Place the one php file in on your web server and modify two lines:

'auth_username' =>      'test',
'auth_password' =>      'e8358914a32e1ce3c62836db4babaa01'

In the first, put your desired username (Duh!), and in the second one put the md5 hash of the following: username:phpMyID:password.  There are many ways to compute this, and the README suggests the following for Unix/OSX:

echo -n 'username:phpMyID:password' | openssl md5

Or the following for Windows:

md5.exe -d"username:phpMyID:password"

I’ll add that you can even get by with:

echo '<? print md5("username:phpMyID:password") ."\n" ?>' | php

Now visit the page you just updated in your browser.  It will identify itself with something like this:  Place this information in both the openid.server and openid.delegate autodisovery links, and  re-verify your setup.

Unlike other implementations, this one avoids using HTML forms for login, and instead uses HTTP digest authentication.  This is a good thing.

Update: phpMyId has changed a bit since the time this was originally written.


So far, you have been able to host your own identity, but let’s face it, the URIs are a bit crufty, eh?.  This shouldn’t matter much to anyone, but cleaning this up a bit will provide a bit of future proofing should you ever want to use a different implementation to host your own identity.

Often you can decruft your openid.server URI simply by renaming the script from MyID.php to index.php.  You may need you to tweak your DirectoryIndex, which in turn may require AllowOverride Indexes to be set in your Apache configuration.  Simply by doing this, my decrufted server is now:

Decrufting your openid.delegate is even easier.  Simply find the line in the php script that sets $idp_url and add another line after it which sets it to the value you want it to be.  By setting it to my weblog address, I can eliminate the need for a openid.delegate autodiscovery link entirely!

$idp_url = '';


At this point, I have two Identities, but I can only declare one, and can only declare it in a rather fragile and HTML specific manner.  This is good enough for most purposes, and one can certainly stop there.

But let’s not.

YADIS defines a simple format for declaring multiple identities, potentially using multiple different protocols.  Here’s what mine looks like so far:

<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)"

    <Service priority="1">

    <Service priority="2">


Not too bad, eh?  Two services, one of a lower numerical (and therefore higher logical) priority that I host myself, and one using MyOpenID; both associated with  This information is simultaneously richer, more extensible, and easier to consistently parse than autodiscovery links placed in HTML as practiced on the web today.  Just be sure to return this information with the correct MIME type:

AddType application/xrds+xml .xrdf

Now, how do I connect it in with my weblog?  It turns out that there are multiple ways, so let me start out with what I consider the best way to be: redirecting requests based on the value of the HTTP accept header, thus:

RewriteCond %{HTTP_ACCEPT} application/xrds\+xml
RewriteCond %{HTTP_ACCEPT} !application/xrds\+xml\s*;\s*q\s*=\s*0(\.0{1,3})?\s*(,|$)
RewriteRule ^$ [R,L]

I like that way best because tools looking for my identity don’t first have to fetch my blog at all.  The next best way involves a HTTP header which you can set thus:

<Files index.html>
  Header onsuccess set X-XRDS-Location

Finally, one can put this information in the HEAD sections of HTML documents, but only as a last resort:

<meta http-equiv="X-XRDS-Location" content="">

As always, when done, check your setup.  In fact, you might find it instructive to check mine.


Astute readers will note that I still have the link in my main weblog home page.  That’s a fallback for consumers that don’t (yet) support YADIS.

All told: I signed up for one free service, installed and tailored one PHP script, added one line to my weblog template, created one simple XML file and added a total of four lines to my .htaccess files.