My micro-blogging backup tool fell over recently because Twitter switched to OAuth exclusively. Here's how I got it working again.

A short while ago, Twitter disabled basic authentication. That means that all clients that want to talk to the API must use OAuth. Naturally, that killed my microblogging backup tool. (A series of essays I am painfully aware is as yet still unfinished.)

To work around this problem, I implemented XQuery-OAuth. (Fair warning: there are a couple of MarkLogic-specific functions in there, but it shouldn't be hard to adapt to other systems if you need to.)

The oauth.xqy module provides a function for accessing web services authenticated with OAuth. I'm going to assume you know at least as much about OAuth as I do. That's a pretty safe bet since I don't know all that much.

The heart of the API is the <service-provider> document. I've attempted to document this format with a schema. (I know, schemas aren't documentation, would you be happier if I hadn't provided even that much?) This document provides the API with the information it needs to contact the service provider for a request token, user authorization, user authentication, and an access token. It describes the signature methods that the service provider accepts and the application-level authentication of the caller.

In theory, this information is sufficient to perform the entire hand-shaking process necessary to authenticate a user.

In practice, I've only tested a small part of the API in anger.

For me, the hardest part of using OAuth authenticated services for my own applications is getting past the initial handshake stage. In brief, if you start with a consumer key and a consumer secret (the things that authenticate the application), you can extract from the service an access token and access token secret that allow you to make authenticated calls to the service provider's API.

I've used this Perl script to successfully extract the access information from Twitter.

After you have all the tokens, you can issue a signed request by calling oa:signed-request. For example, suppose that I want to get the first 25 statuses on my user timeline from Twitter. I'd do something like this:

  1let $service-document
  2  := <oa:service-provider realm=""></oa:service-provider>
  3let $access-token := "MY ACCESS TOKEN"
  4let $access-token-secret := "MY ACCESS TOKEN SECRET"
  5let $options
  6  := <oa:options>
  7       <screen_name>ndw</screen_name>
  8       <count>25</count>
  9       <page>1</page>
 10     </oa:options>
 11return
 12  oa:signed-request($service-document,
 13                    "GET", "http://twitter.com/statuses/user_timeline.xml",
 14                    $options, $access-token, $access-token-secret)

I already had a single entry-point for making API calls to twitter, so as soon as I fixed that function, my whole system started working again.

Scant on detail, I know, but I hope this helps someone.

Comments:

[microblogging backup] href is wrong. It should point to http://norman.walsh.name/2009/08/27/mbb01.

--lm

Posted by Luis Miguel on 27 Sep 2010 @ 06:51am UTC #

Thanks, Luis. Fixed now.

Posted by Norman Walsh on 04 Oct 2010 @ 08:53pm UTC #

Your perl script link is broken.

Posted by Luis Larrea on 27 Oct 2010 @ 08:07pm UTC #

Fixed now. Sorry about that.

Posted by Norman Walsh on 28 Oct 2010 @ 07:42pm UTC #

Does this still work with Twitter now? MarkLogic now has a built-in function for HMAC-SHA1 if I'm not mistaken.

Posted by Ryan Semerau on 06 Feb 2012 @ 11:03pm UTC #

It runs every day, collecting input for my "shortform" essays. I think you're right about the SHA function, but I haven't updated it for MarkLogic 5 yet.

When I have a free moment, I'll see about revisiting the app.

Posted by Norman Walsh on 09 Feb 2012 @ 12:17pm UTC #
Comments on this essay are closed. Thank you, spammers.