Using OAuth with the Google Data APIs

Eric Bidelman, Google Data APIs team
September 2008

Introduction

It's an exciting time for developers. We're starting to see a number of open standards being adopted across the web, and as you know, Google has always been a huge fan of standards and fostering the open source community.

Recently, all of the Google Data APIs adopted support for OAuth, an open protocol that aims to standardize the way desktop and web applications access a user's private data. OAuth provides a means of performing API authentication in a standard and secure fashion. As programmers, we're taught to reuse code wherever possible. OAuth will help developers reduce the amount of duplicate code they write and make it easier to create tools that work with multiple services from a variety of different providers.

Audience

This article assumes that you are familiar with one or more of the Google Data APIs but not necessarily the concepts behind OAuth. If you're starting out, or just curious about OAuth, look no further. This article will give you a basic foundation of the concepts. I'll also discuss the details of Google's OAuth implementation.

This document is also meant for developers that are familiar with using AuthSub, especially in registered with enhanced security mode. As we go along, I'll try to highlight the similarities and differences between the two protocols. If you have applications that use AuthSub, you can use this information to migrate to OAuth, which is a more open, modern protocol.


A little terminology

Understanding OAuth is all about understanding its terminology. The OAuth specification and Google's OAuth Authentication for Web Applications documentation rely heavily on certain definitions, so lets clarify what each means in the context of Google's OAuth implementation.

  1. "OAuth dance"

    My unofficial term to describe the full OAuth authentication/authorization process.

  2. (OAuth) Request token

    An initial token that lets Google know your application is requesting access to one of the Google Data APIs. The second step of the OAuth dance is for the user to manually grant access to their data. If this step is successful, the request token becomes authorized.

  3. (OAuth) Access token

    The last step of the dance is to exchange the authorized request token for an access token. Once your application has this token, a user won't need to go through the OAuth dance again, unless the token is revoked.

    Similarity to AuthSub:
    An OAuth access token is the same thing as a secure AuthSub session token.

  4. (OAuth) Endpoints

    These are URIs required to authenticate an application and obtain an access token. There are three total - one for each step of the OAuth process. Google's OAuth endpoints are:

    Obtain a request token:https://www.google.com/accounts/OAuthGetRequestToken
    Authorize the request token:https://www.google.com/accounts/OAuthAuthorizeToken
    Upgrade to an access token:https://www.google.com/accounts/OAuthGetAccessToken

    Similarity to AuthSub:
    Exchanging an authorized request token for an access token is analogous to upgrading a single-use AuthSub token to a long-lived session token at https://www.google.com/accounts/AuthSubRequestToken and https://www.google.com/accounts/AuthSubSessionToken, respectively. The difference is that AuthSub doesn't have the concept of an initial request token. Instead, the user starts the token process from the AuthSubRequestToken authorization page.

  5. (OAuth) Service Provider

    In the case of the Google Data APIs, this provider is Google. In general, the service provider is used to describe the website or web service that provides the OAuth endpoints. Another example of an OAuth service provider is MySpace.

  6. (OAuth) Consumer

    The program requesting permission to access a user's data (i.e. your application). The OAuth protocol is flexible in that it allows for a wide variety of different types of clients (web, installed, desktop, mobile).

Note: Though the OAuth protocol supports the desktop/installed application use case, Google only supports OAuth for web applications.

Getting Started

Registration

There's a small amount of setup before you can start using OAuth with the Google Data APIs. Since all OAuth requests must be digitally signed, you first need to register your domain and upload a public certificate to Google. See Registration for Web-Based Applications and Generating keys and certificates for use with registered mode for more information on how to do that.

Signing requests

Once your domain is registered, you're ready to start signing requests. One of the most difficult concepts of OAuth is how to properly construct the oauth_signature and the notion of the signature base string. The base string is the data that you sign with your private key (using RSA_SHA1). The result is the value you set for the oauth_signature.

Example request

GET a list of a user's Google Calendars at http://www.google.com/calendar/feeds/default/allcalendars/full?orderby=starttime

Base string format base_string = http-method&base-http-request-url&normalized-string-of-oauth_parameters
Example base string GET&http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2Fdefault%2Fallcalendars%2Ffull&oauth_consumer_key%3Dexample.com%26oauth_nonce%3D4572616e48616d6d%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D137131200%26oauth_token%3D1%252Fab3cd9j4ks73hf7g%26oauth_version%3D1.0%26orderby%3Dstarttime
Example HTTP request
GET http://www.google.com/calendar/feeds/default/allcalendars/full?orderby=starttime HTTP/1.1
Host:  http://www.google.com
Content-Type: application/atom+xml
Authorization: OAuth oauth_token="1%2Fab3cd9j4ks73hf7g", oauth_signature_method="RSA-SHA1", oauth_signature="wOJIO9AvZbTSMK%2FPY%3D...", oauth_consumer_key="example.com", oauth_timestamp="137131200", oauth_nonce="4572616e48616d6d", oauth_version="1.0"

Note: This is only meant as representation. Your oauth_signature will be much longer.

Notes on the base string:

  • The orderby=starttime query parameter is sorted along with the rest of the oauth_* parameters in lexicographical byte value ordering.
  • This string also does not contain a '?' character.
  • The base-http-request-url portion only contains the url-encoded base url: http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2Fdefault%2Fallcalendars%2Ffull.
  • The oauth_token is double url-encoded.

Notes on the Authorization header:

  • The ordering of the oauth_* parameters does not matter in the Authorization header.
  • The header does not include the orderby=starttime as the base string did. That query parameter is maintained as part of the request URL.

For more information on signing requests using OAuth, see Signing OAuth Requests.

Difference from AuthSub:
As a comparison, here is the same example using secure AuthSub:

Base string format base_string = http-method http-request-URL timestamp nonce
Example base string
GET http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2Fdefault%2Fallcalendars%2Ffull%3Forderby%3Dstarttime 137131200 4572616e48616d6d
Example HTTP request
GET http://www.google.com/calendar/feeds/default/allcalendars/full?orderby=starttime HTTP/1.1
Host:  http://www.google.com
Content-Type: application/atom+xml
Authorization: AuthSub token="GD32CMCL25aZ-v____8B" data="GET http://www.google.com/calendar/feeds/default/allcalendars/full?orderby=starttime 137131200 4572616e48616d6d" sig="MCwCFrV93K4agg==..." sigalg="rsa-sha1"

For more information on signing requests using AuthSub, see Signing AuthSub Requests.

OAuth Playground Tool

Purpose

Some users have suggested that OAuth has a high learning curve. Compared to Google's other authentication APIs, I would agree. The advantage of OAuth will be apparent when you expand your app to use other (non-Google) services. Writing a single piece of authentication code that works across different service providers, and their APIs, sounds pretty good to me. You'll thank yourself later on for learning the protocol now.

The OAuth Playground is a tool that I created to help developers cure their OAuth woes. You can use the Playground to help debug problems, check your own implementation, or experiment with the Google Data APIs.

What does it do?

  1. Illustrates the OAuth authentication flow: fetching a request token, authorizing the token, and upgrading it to an access token.
  2. Displays the correct signature base string for each request.
  3. Displays the correct Authorization header for each request.
  4. Demonstrates how use an oauth_token to interact with an authenticated Google Data feed. You can GET/POST/PUT/DELETE data.
  5. View an authenticated feed directly in your browser.
  6. Allows you to test your own oauth_consumer_key (your registered domain) and private key.
  7. Discover what Google Data feed services are available to your oauth_token.

Demo Run

Step 1: Choose your Scopes(s)

First, decide which APIs you want to use by choosing one or more scopes. In this demonstration, I'm requesting a token that will work with Blogger and Google Contacts.

Similarity to AuthSub:
AuthSub also requires the scope parameter to control the range of data a token can access. Google has implemented this parameter as suggested in the OAuth spec.

Step 2: Modify OAuth Parameters and Settings

For now, don't modify any settings in the "Modify the OAuth Parameters" box. Later on, you can test with your own private key by changing the oauth_consumer_key to your registered domain and entering your private key by clicking "use your own private key". Please only use a TEST private key.

Note: The oauth_signature_method and oauth_consumer_key are the only fields that are editable here. The oauth_timestamp, oauth_nonce, and oauth_token will be automatically generated for you.

In addition to RSA-SHA1, you may choose to use HMAC-SHA1 for the oauth_signature_method. In that case, the Playground will show additional boxes where you will need to input your own oauth_consumer_key and consumer secret. These values can be found under the https://www.google.com/accounts/ManageDomains page for your registered domain.

Difference from AuthSub:
In secure AuthSub, there's no parameter to explicitly set a domain name. The domain is included as part of the next URL parameter. There is such a parameter in OAuth: oauth_consumer_key. Set it to your registered domain.

Step 3-5: Acquire the access token

There are three steps to getting an OAuth access token. The first step is to retrieve a request token. This lets Google know your application is starting the OAuth dance.

First, click the "Request token" button in the "Get the Token" box.

Certain fields will populate with data.

  • The "Signature base string" displays the proper form of the base string used to create the oauth_signature parameter.
  • The "Authorization header" displays the corresponding Authorization header for the request.
  • The "Modify the OAuth Parameters" box filled with the oauth_nonce and oauth_timestamp values sent in the request.
  • The oauth_token input was populated with the corresponding value returned in the response body. The Playground also displays what type of oauth_token we currently have. At the moment, it's a request token.

Next, click the "Authorize" button in the "Get the token" box.

On this authorization page, click the "Grant Access" button to authorize the request token and be redirected back to the OAuth Playground.

Similarity to AuthSub:
This authorization page is the same for AuthSub.

Difference from AuthSub:
AuthSub's next URL parameter is analogous to the oauth_callback parameter. The difference is that in OAuth the oauth_callback is optional. After the user clicks the "Grant access" button the request token becomes authorized and the token upgrade to https://www.google.com/accounts/OAuthGetAccessToken can be performed asynchronously.

Tip: Specifying a oauth_callback URL is preferred if you're writing a web application because it provides a better user experience.

Lastly, click the "Access token" button in the "Get the Token" box.

This action upgrades the authorized request token (as noted by the red "access token") label.

If you want to fetch a new token, click "start over" to re-initiate the OAuth dance.

Now we can do something interesting!

Using the access token

Now you're ready to query feeds, insert, update, or delete data. Please take care when performing these last three HTTP methods as you're working with your real data!

Tip: To discover feeds that are available to your access token, click the "available feeds" button.

Here's an example query: GET http://www.blogger.com/feeds/1982051675575479214/posts/default?max-results=3

This example returns no more than three posts on a particular blog. You can also view the returned feed/entry directly in your browser by clicking the "View in browser" link below the syntax highlighted area.

Example: How to update a post

  1. Locate the <link> element with a rel="edit" in the post you want to update. It should look something like:
    <link rel="edit" href="http://www.blogger.com/feeds/1982051675575479214/posts/default/8138973184593279875"/>

    Paste the href URL in the "Enter a Google Data feed" input.

  2. Copy the existing entry's XML by clicking "view plain" at the top of the syntax highlighted panel. Only copy the response body, not the headers.
  3. Change the HTTP method dropdown to PUT.
  4. Click "enter post data" below that dropdown and paste the <entry> XML into the popup.
  5. Click the "execute" button.

The server will respond with a 200 OK.

Tip: Instead of manually copying the edit link, uncheck the 'Syntax Highlight?' checkbox. After a query, you'll be able to click on the links within the XML response bodies.

Conclusion

Technologies like the AtomPub/Atom Publishing Protocol (underlying protocol of the Google Data APIs) and OAuth help to drive the web forward. As more and more sites begin to embrace these standards, we developers are the winners. Creating a killer app suddenly becomes less daunting.

If you have any questions or comments on the OAuth Playground, or using OAuth with Google APIs, please visit us in the G Suite APIs and Marketplace APIs Support Forum.

Resources