Marko Anastasov wrote this on March 2, 2010
Authentication methods in popular web APIs
Recently we did a little survey of authentication methods used for APIs of well known web applications. It’s great to see big players moving away from the password anti-pattern and embracing OAuth, an open standard in this field, for which the old guard paved the way.
Perhaps you’re wondering why passwords are really so bad. While it is debatable whether OpenID is better for everyone than password-based login, giving away your password to a third party is never a good idea. Have you ever entered your webmail password on a site that wanted to import your contacts? Are you sure that it was used appropriately, or worse, that you were not phished?
You should always keep in mind that you own your data and that includes a right to transfer it as you please without putting your security in danger. For a discussion about the password anti-pattern, read this article by Jeremy Keith.
OAuth and Twitter
OAuth is a protocol that appeared shortly after OpenID. The idea is to provide a common and secure way to allow people to share their private resources stored on one site with another site without having to provide their username and password.
Twitter is often the first example people think of when talking about OAuth. Indeed it was born out of work on the Twitter OpenID implementation. Although they support Basic HTTP authentication as well, the plan is to deprecate it in June.
Now we will explain how an OAuth session works using the twitter_oauth gem as a source example:
- Client application (that wants to get some access to a person’s Twitter account) gets a consumerkey and consumersecret from Twitter.
- Client sends a request with that data along with a callback URL; Twitter responds with a URL where user should go and authorize the client application.
- Once the user clicks on a button to allow client app the access, Twitter redirects to the app’s callback URL, providing oauthverifies, accesstoken and access_secret.
- Client app now knows how to make authorized requests to the API. OAuth calls are basically HTTP calls with a bunch of standardized parameters (see Appendix 5 of the spec). Applications use wrapper libraries for their language, something like OAuth::AccessToken.
They’re using OAuth as well.
All methods require user to go to the Flickr web site and review the authorization request. For web, there’s a callback URL. For desktop, there’s an additional method call which the user initiates after authorization, within the desktop app. For mobile, user needs to write down a nine digit key, and enter it on their phone.
Last.fm API also differentiates web, desktop and mobile access. As on Flickr, web and desktop work similar to OAuth. Apps get an API key and secret. After user authorizes the app, it gets an API token. There is then an API signature, which is computed as an MD5 sum as per a provided formula, and a session key, retrieved with a method call. Protected API methods require the session key, API key and API signature (another MD5 sum). The parameters must be ordered alphabetically.
For mobile applications, there’s a getMobileSession method. Here username and password come into play, as they are used to compute the authentication token and API signature, the parameters for getting the session key.
Basecamp (and now the 37signals login system) lets users choose between OpenID and password authentication. However the Basecamp API uses only Basic authentication — users with na OpenID have a special username and password that they need to use. For its target audience, this is not a huge usability issue.
On Disqus, every user has their own API key which they can see while logged in on the Disqus web site. Using that key and one method call, you can get a forum_key (which you can think of as your blog’s API key). From that point, you have full access. In some cases you may also need to provide forum or post ID, which are also easily GET-able using these two keys.
FriendFeed supports OAuth, Installed Application Authentication (IAA) and HTTP Basic authentication.
IAA is like a modified OAuth, where access tokens are retrieved using a username and password, and not through the browser via a request URL. It is built for desktop and mobile applications which then make GET requests with defined options. Access tokens are invalidated when user changes her password.
While new projects should implement OAuth for authorizing user actions, or have a simple API like Disqus, it is worth noting that OAuth also has some minor limitations. While the redirection workflow still doesn’t completely elliminate the phishing problem (it might just be a sociological problem as well), it is the mobile and embedded applications that are facing the biggest hurdle, as they may not be able to bring up and/or control the web browser.
Twitter team has recently proposed xAuth, a way to get OAuth tokens with a username and password. However there is still no clear solution how a mobile application which cannot launch a browser would access an OAuth-based API of a site that lets people log in with OpenID. Here’s one possible approach:
- Inside the app, user enters their account ID (username or screen name).
- App sends a request to the site with an API key, and gets all OAuth access tokens for that account ID. It is then able to fully access the API.
- User receives an email saying “App ‘X’ now has access, you can revoke it on (…) and see all applications you’ve authorized on (…)”
- On the server, access tokens are linked to user accounts and registered applications. By revoking access, user would permanently invalidate the tokens and send a signal that app ‘X’ might be harmful.