Client Profiles, Access Tokens, and Authorization Flows

The first version of OAuth was designed primarily to handle API authorization for classic client-server web applications. The specification did not define how to handle authorization in mobile applications, desktop applications, JavaScript applications, browser extensions, or other situations. While each of these types of apps have been written using OAuth 1.0, the method of implementation is inconsistent and often suboptimal, as the protocol wasn’t designed for these cases.

OAuth 2.0 was architected with this variety of use cases in mind.

Client Profiles

OAuth 2.0 defines several important client profiles:

Server-side web application

An OAuth client running on a web server. The web application is accessed by a resource owner (user) and the application makes the appropriate API calls using a server-side programming language. The user has no access to the OAuth client secret or any access tokens issued by the authorization server.

Client-side application running in a web browser

An OAuth client running in a user’s web browser, where the client has access to the application code and/or API requests. The application could be distributed as JavaScript included in a web page, as a browser extension, or using a plug-in technology such as Flash. The OAuth credentials are not trusted to be kept confidential from the resource owner, so some API providers won’t issue client secrets for applications using this profile.

Native application

An OAuth client which is very similar to the client-side application, as the credentials are not trusted to be kept confidential. However, since it’s an installed application, it may not have access to the full capabilities of a web browser.

Access Tokens

Although signature-based MAC Access Authentication was mentioned earlier, most OAuth 2.0 authorized APIs require only bearer tokens to make authorized requests. Bearer tokens are a type of access token whereby simple possession of the token values provides access to protected resources. No additional information, such as a cryptographic key, is needed to make API calls.

Whether you're building a server-side web application, client-side web application, or a native application, the end goal of using OAuth is the same: you’re trying to obtain an OAuth access token that your application can use to perform API requests on behalf of a user or the application itself.

After obtaining an access token, the token can be sent along with your requests in one of several ways. The preferred method of authorizing requests is by sending the access token in a HTTP Authorization header:

GET /tasks/v1/lists/@default/tasks HTTP/1.1 
Host: www.googleapis.com
Authorization: Bearer ya29.AHES6ZSzX

The Authorization header is the preferred mechanism because

  • The header is rarely logged by proxy servers and web server access logs.

  • The header is almost never cached.

  • The header doesn’t get stored in the browser cache when making requests from the client.

While the other mechanisms are defined in the specification, API providers are not required to implement any of these additional methods, so your mileage will vary:

Query parameter

Including the access_token as a URL query parameter is useful for debugging and when libraries make it difficult to modify the Authorization header. This mechanism is also valuable when using the client-side flow and sending a token in a JSONP request. For example,

https://www.googleapis.com/tasks/v1/lists/@default/tasks?callback=outputTasks&access_token=ya29.AHES6ZTh00gsAn4
Form-encoded body parameter

This is a fallback mechanism for when an application cannot modify the Authorization header on requests. It is only to be used when a HTTP body would normally be sent and can then be added as an additional form parameter in an application/ x-www-form-urlencoded body. This mechanism is not supported by the Google Tasks API.

Authorization Flows

Each of the client profiles needs to be accommodated with an appropriate protocol flow for obtaining authorization from the resource owner for access to their data. The core OAuth 2.0 protocol defines four primary “grant types” used for obtaining authorization and also defines an extension mechanism for enabling additional grant types.

Authorization code

This grant type is most appropriate for server-side web applications. After the resource owner has authorized access to their data, they are redirected back to the web application with an authorization code as a query parameter in the URL. This code must be exchanged for an access token by the client application. This exchange is done server-to-server and requires both the client_id and client_secret, preventing even the resource owner from obtaining the access token. This grant type also allows for long-lived access to an API by using refresh tokens.

Implicit grant for browser-based client-side applications

The implicit grant is the most simplistic of all flows, and is optimized for client-side web applications running in a browser. The resource owner grants access to the application, and a new access token is immediately minted and passed back to the application using a #hash fragment in the URL. The application can immediately extract the access token from the hash fragment (using JavaScript) and make API requests. This grant type does not require the intermediary “authorization code,” but it also doesn’t make available refresh tokens for long-lived access.

Resource owner password-based grant

This grant type enables a resource owner’s username and password to be exchanged for an OAuth access token. It is used for only highly-trusted clients, such as a mobile application written by the API provider. While the user’s password is still exposed to the client, it does not need to be stored on the device. After the initial authentication, only the OAuth token needs to be stored. Because the password is not stored, the user can revoke access to the app without changing the password, and the token is scoped to a limited set of data, so this grant type still provides enhanced security over traditional username/password authentication.

Client credentials

The client credentials grant type allows an application to obtain an access token for resources owned by the client or when authorization has been “previously arranged with an authorization server.” This grant type is appropriate for applications that need to access APIs, such as storage services or databases, on behalf of themselves rather than on behalf of a specific user.

These additional flows are defined outside of the core spec:

Device profile

The device profile was created to enable OAuth to be used on devices that do not have built-in web browsers or have limited input options—such as a game console or electronic photo frame. The user typically initiates the flow on the device and is then told to use a computer to access a website and approve access for the device by typing in an authorization code displayed in the device. Facebook has a great example of this flow referenced in its documentation.

SAML bearer assertion profile

This profile enables exchanging SAML 2.0 assertion for an OAuth access token. This is useful in enterprise environments that already have SAML authorization servers set up to control application and data access.

Get Getting Started with OAuth 2.0 now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.