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.)
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
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?)
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
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.