Chapter 5: Authentication, part 2
By Bryan Cooksey • Published April 22, 2014
In Chapter 4, we mentioned most websites use a username and password for authentication credentials. We also discussed how reusing these credentials for API access is insecure, so APIs often require a different set of credentials from the ones used to login to the website. A common example is API keys. In this chapter, we look at another solution, Open Authorization (OAuth), which is becoming the most widely used authentication scheme on the web.
Making life easy for people
Have you ever had to complete a registration form like the one below?
Typing a long key into a form field like the one above makes for a poor user-experience. First, you have to find the required the key. Sure, it was right in your inbox when you bought the software, but a year later, you're scrambling to find it (What email was it sent from? Which email did I use to register?!) Once located, you have to enter the darned thing perfectly - making a typo or missing a single character will result in failure, or might even get you locked out of your unregistered software!
Forcing users to work with API keys is a similarly poor experience. Typos are a common problem and it requires the user to do part of the setup between the client and server manually. The user must obtain the key from the server, then give it to the client. For tools meant to automate work, surely there's a better solution.
Enter OAuth. Automating the key exchange is one of the main problems OAuth solves. It provides a standard way for the client to get a key from the server by walking the user through a simple set of steps. From the user's perspective, all OAuth requires is entering credentials. Behind the scenes, the client and server are chattering back and forth to get the client a valid key.
There are currently two versions of OAuth, aptly named OAuth 1 and OAuth 2. Understanding the steps in each is necessary to be able to interact with APIs that use them for authentication. Since they share a common workflow, we will walk through the steps of OAuth 2, then point out the ways in which OAuth 1 differs.
To get started, we first need to know the cast of characters involved in an OAuth exchange:
- The User - A person who wants to connect two websites they use
- The Client - The website that will be granted access to the user's data
- The Server - The website that has the user's data
Next, we need to give a quick disclaimer. One goal of OAuth 2 is to allow businesses to adapt the authentication process to their needs. Due to this extendable nature, APIs can have slightly different steps. The workflow shown below is a common one found among web-based apps. Mobile and desktop applications might use slight variations on this process.
With that, here are the steps of OAuth 2.
Step 1 - User tells client to connect to server
The user kicks off the process by letting the client know they want it to connect to the server. Usually, this is by clicking a button.
Step 2 - Client directs user to server
The client sends the user over to the server's website, along with a URL that the server will send the user back to once the user authenticates, called the callback URL.
Step 3 - User logs-in to server and grants client access
With their normal username and password, the user authenticates with the server. The server is now certain that one of its own users is requesting that the client be given access to the user's account and related data.
Step 4 - Server sends user back to client, along with code
The server sends the user back to the client (to the Callback URL from Step 2). Hidden in the response is a unique authorization code for the client.
Step 5 - Client exchanges code + secret key for access token
The client takes the authorization code it receives and makes another request to the server. This request includes the client's secret key. When the server sees a valid authorization code and a trusted client secret key, it is certain that the client is who it claims to be and that it is acting on behalf of a real user. The server responds back with an access token.
Step 6 - Client fetches data from server
At this point, the client is free to access the server on the user's behalf. The access token from Step 6 is essentially another password into the user's account on the server. The client includes the access token with every request so it can authenticate directly with the server.
Client refreshes token (optional)
A feature introduced in OAuth 2 is the option to have access tokens expire. This is helpful in protecting users' accounts by strengthening security - the faster a token expires, the less time a stolen token might be used maliciously, similar to how a credit card number expires after a certain time. The lifespan of a token is set by the server. APIs in the wild use anything from hours to months. Once the lifespan is reached, the client must ask the server for a new token.
How OAuth 1 is different
There are several key differences between the versions of OAuth. One we already mentioned; access tokens do not expire.
Another distinction is that OAuth 1 includes an extra step. Between Steps 1 and 2 above, OAuth 1 requires the client to ask the server for a request token. This token acts like the authorization code in Oauth 2 and is what gets exchanged for the access token.
A third difference is that OAuth 1 requires requests to be digitally signed. We'll skip the details of how signing works (you can find code libraries to do this for you), but it is worth knowing why it is in one version and not the other. Request signing is a way to protect data from being tampered with while it moves between the client and the server. Signatures allow the server to verify the authenticity of the requests.
Today, however, most API traffic happens over a channel that is already secure (HTTPS). Recognizing this, OAuth 2 eliminates signatures in an effort to make version two easier to use. The trade-off is that OAuth 2 relies on other measures to provide security to the data in transit.
An element of OAuth 2 that deserves special attention is the concept limiting access, known formally as authorization. Back in Step 2, when the user clicks the button to allow the client access, buried in the fine print are the exact permissions the client is asking for. Those permissions, called scope, are another important feature of OAuth 2. They provide a way for the client to request limited access to the user's data, thereby making it easier for the user to trust the client.
What makes scope powerful is that it is client-based restrictions. Unlike an API Key, where limits placed on the key affect every client equally, OAuth scope allows one client to have permission X and another permissions X and Y. That means one website might be able to view your contacts, while another site can view and edit them.
Chapter 5 Recap
In this chapter, we learned the flow of the OAuth authentication process. We compared the two versions, pointing out the major difference between them.
The key terms we learned were:
- OAuth: an authentication scheme that automates the key exchange between client and server.
- Access Token: a secret that the client obtains upon successfully completing the OAuth process.
- Scope: permissions that determine what access the client has to user's data.
In the next chapter, we look at some of the basics concepts in API design, including how APIs organize their data so the client can easily access what it wants.