OpenID delegation under Django and lighttpd

Published: January 8, 2007. Filed under: Django, Meta.

There’s been lots and lots and lots of buzz around OpenID in the last couple weeks, which makes me happy because OpenID is a pretty darned cool system. Simon is doing all sorts of cool things, and Sam Ruby wrote up wonderful step-by-step instructions for OpenID delegation, which lets you use your own domain name to sign in with OpenID even if your OpenID is hosted somewhere else.

I sat down tonight and worked out how to set it up here, because that’s a nifty and useful trick; Sam’s Apache rewrite rules are all you’ll need if you’re under Apache, but if you’re running lighttpd (as I am) it’s a bit trickier; where Apache’s mod_rewrite lets you conditionally redirect based on pretty much anything, lighttpd’s support for conditionals based on HTTP headers seems to be limited to Host, User-Agent and Referer (if I’m wrong about this, I’d love to know it; that would make my life simpler).

So I moved things up one level into Django, where I have finer-grained control; where before, the home page of this site was just the date_based.archive_index generic view, now there’s a short home_page view which wraps it:

import mimeparse
def home_page(request):
    if request.META.has_key('HTTP_ACCEPT') and \
    mimeparse.best_match(['text/html', 'application/xrds+xml'],
                         request.META['HTTP_ACCEPT']) == 'application/xrds+xml':
        return HttpResponseRedirect('/media/files/yadis.xrdf')
    else:
        return archive_index(request,
                             queryset=Entry.objects.all(),
                             date_field='pub_date',
                             num_latest=1,
                             template_name='weblog/home_page.html')

Basically, this means that most requests still get the generic view, but if the Accept header includes application/xrds+xml (the MIME-type for the YADIS XML format which I’m using to declare an OpenID identity) and indicates a preference for it over HTML, then a redirect will be issued to my YADIS file. So far, it seems to be working.

Updated: thanks to Jacob’s suggestion in the comments, I’m now doing this more robustly using Joe Gregorio’s lovely mimeparse library.