OpenID delegation under Django and lighttpd

An entry published by James Bennett on January 8, 2007, Part of the categories Django and Meta. Three comments posted.

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.

On January 8, 2007, Nicolas said:

Hmm, didn’t know about the “foo” in bar Python construct, cool! Changed that in DjangoID ;-) You could use a meta tag on your index page too: or add a corresponding HTTP header (although afaik this is deprecated): X-XRDS-Location: http://yadis_uri

I just implemented all methods, this way “it just works”, not matter which method the consumer uses.

Nicolas

PS. When is OpenID login on your site coming? ;-)

On January 8, 2007, Nicolas said:

Looks like the comment got screwed a little, the meta tag example is gone, so are my linebreaks. Oh well…

On January 8, 2007, Jacob Kaplan-Moss said:

If you wanted to be really robust about your accept header parsing, you could use Joe Gregorio’s mimeparse library.

Comments for this entry are closed. If you'd like to share your thoughts on this entry with me, please contact me directly.

ponybadge