HTTP API authentication has evolved through many forms over the years. As so-called RESTful APIs gained popularity, a variety of methods sprung up: key passing, plain-old HTTP Basic Auth, OAuth 1.0, OAuth 1.0a, OAuth 2.0 (and it’s 40 revision) and some less-common custom schemes. With the OAuth 2.0 specification finalized, things are finally starting to settle down and coalesce around a single auth mechanism. For publicly-available APIs, OAuth 2.0 should be on your list of requirements.

The most important thing to remember when implementing OAuth 2.0 is this: don’t be clever. The spec is big and scary, but thorough. There has been a lot of thought put into all of those requirements and you should take care to read through them carefully. Any deviation from the spec will result in consumers of your API having to learn a new concept or alter a pre-built library to work with your API. Custom implementations are non-obvious (even if well-documented) and will make for a frustrating developer experience.

Not every API requires a full OAuth 2.0 implementation. For the rest, I recommend keeping it as simple as possible. The two most common simple auth schemes are key passing and HTTP basic auth. In either case, if the traffic is going over the public internet you should require HTTPS to prevent any man-in-the-middle sniffing of API credentials. Support for basic auth is built in to every HTTP library and is well-understood so use that whenever possible.

If you implement OAuth 2.0, don’t forget about the first-run developer experience. Requiring the developer to set up the web infrastructure required to go through the auth flow and obtain a token for testing is an unnecessary burden. While there are tools to help with this, make it easy for the developer to generate a token from your web interface (App.net does a great job of this). Alternately you can support basic auth just for the developer that created the application so they can get up and running faster.

Validating Credentials

It is useful to provide a method to determine if credentials are valid. The root URL is a good place for this:

# basic auth example request api.example.com GET / Authorization: Basic (base64 encoded credentials here) # oauth 2.0 example request api.example.com GET /?access_token=foo

If successful the API should return some basic info about the user. We could add more information to the root response if we want to support hypermedia operations, but that’s for another post.

HTTP/1.1 200 OK Content-Type: text/json { "organization" : { "name" : "Runscope", "id" : "O94107" }, "user" : { "name" : "John Sheehan" "id" : 123 "subscription_expires" : 1356976799 } }

Error Messages

If the credentials are invalid, the API will return an error. Here’s an example of an error response that could be returned on any resource that is accessed with invalid credentials.

HTTP/1.1 401 Unauthorized Content-Type: text/json { "error" : { "code" : 401 "message" : "The credentials provided are invalid." "more_info_url" : "http://example.com/help/errors/401" } }

Side note: You may be asking, why not just put the error information at the top level of the JSON returned? If you’re using a dynamic language to parse your JSON it’s a little less typing to have the error data at the top level. If you are using something strongly-typed you’ll want to have responses from a single endpoint that don’t conflict with each other. This is a lesson I’ve learned from RestSharp. If you can’t map all of the responses from a single endpoint to a single class definition (even if you’re only partially populating it), you’re in for a world of hurt trying to wrangle around it.

With a simple request to / we can now validate credentials and get other important information about the user to display in our app.

Conclusion

By using standardized, common authentication schemes you can reduce the cognitive overhead for the developer consuming your API and avoid getting into unfamiliar, untested security situations. Authentication is the first thing any developer using your API will have to deal with and it’s those first few moments that are crucial to their success using your API to solve their problem. Take care to make the first impression a good one.