OAuth By Example
Mark Cornick, Former Viget
OAuth is, according to its creators, “[a]n open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.” It accomplishes this primarily by passing various tokens and secrets between the API provider and the application wishing to access it. Understanding what happens with these tokens and secrets (which I will call “credentials” for the sake of clarity) makes OAuth slightly less “simple” to comprehend at first. Fortunately, it’s not too hard, and in this post I’ll share what I learned when implementing an OAuth-speaking client application.
Yammer, a private micro-blogging service for businesses, uses OAuth for its API. If I have a Yammer account, I can post status messages throughout the day. For a third-party application to access my messages via the API, I have to authorize the application by going to a special page on Yammer’s site and clicking a “Yes, this is okay” button. This only needs to be done once, but it does need to be done.
Laika is an application that depends on OAuth. Laika takes posts from an RSS feed and sends them to Yammer. At Viget, we use it to funnel our internal blog into our Yammer site, much as we funnel our public blogs into Twitter. Ordinarily, Laika runs once an hour from a cron job, without user intervention. However, it can’t do this until it has clearance from Yammer’s OAuth system.
Fortunately, when Yammer authorizes an application with OAuth, it does so indefinitely, until the user de-authorizes the application. So once we’ve got an authorization, we can cache it somewhere and play it back as needed. I’ll explain how we did this in Laika (it might be helpful at this point to open Laika on GitHub and follow along in the code.)
OAuth depends on two sets of credentials: a “client” token and secret, and an “access” token and secret. The client credentials identify an application to the provider, and the access credentials permit the application to access a particular set of data. The client credentials come first. For most OAuth provider sites, you will go to a web page on the site and register your application; you will then get your credentials, which consist of two cryptographic hashes.
Once you have the client credentials, you can request access credentials. One way to do this is to prompt for the client credentials, then send the user to the OAuth provider’s site to obtain access credentials, once you have the access credentials, you’d store them for future use. Since Laika runs non-interactively, we can’t do this from within Laika itself, so we have an interactive application, called “Laika-auth”, that runs once, obtains everything from Yammer that’s needed to authenticate, and stores it for Laika to use later.
Laika-auth is pretty straightforward. We expect that the user has already registered for client credentials, so we prompt for them. With client credentials, we can ask for our request token and secret. Yammer responds to this request with the URL of a page where we will authorize Laika to access our Yammer posts. With that done, Yammer sends the request token and secret back to Laika-auth, which writes all four pieces of information (client token and secret, access token and secret) into a YAML file. (You would likely use your database, instead of a YAML file, in a Rails application.)
In Laika itself, we create a new Yammer object, which loads the YAML file written by Laika-auth and creates two objects, each authenticated by one of the two sets of credentials. The consumer comes first; once we have that, we can create an AccessToken object, which we will use to interact with Yammer via its RESTful API.
Did you notice the similarities in the processes described in the last two paragraphs? We authorize the client, then authorize it to access data. However, in Laika, we’re just replaying an authorization that we completed in Laika-auth. This is the key to understanding OAuth: once you’ve done the authorization dance to get your credentials, those credentials are good until revoked. That’s why we store them in our YAML file or database.
This probably still seems complicated compared to just having Laika authenticate with the same username and password I use to access Yammer myself. Consider what happens when I change my Yammer password: I would need to go back to Laika, and whatever other appications I have given my username and password to, and fix each one. Furthermore, I trust Laika, because I wrote it, but do I necessarily trust other sites or applications with my Yammer password? I probably shouldn’t. By using these cryptographic credentials instead of passwords, I can authorize applications without exposing my password, change my password without breaking everything else, and deauthorize one application without breaking all the others. That’s the big win for OAuth, and what you gain from doing all this passing hashes around.
OAuth is in active development, but hasn’t really reached critical mass yet, so now is a good time to try writing an OAuth client of your own. Then you’ll be ready when OAuth hits the big time.