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.
- "OAuth dance"
My unofficial term to describe the full OAuth authentication/authorization process.
- (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.
- (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. - (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 athttps://www.google.com/accounts/AuthSubRequestToken
andhttps://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 theAuthSubRequestToken
authorization page. - (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.
- (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 theoauth_*
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 theAuthorization
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?
- Illustrates the OAuth authentication flow: fetching a request token, authorizing the token, and upgrading it to an access token.
- Displays the correct signature base string for each request.
- Displays the correct
Authorization
header for each request. - Demonstrates how use an
oauth_token
to interact with an authenticated Google Data feed. You canGET
/POST
/PUT
/DELETE
data. - View an authenticated feed directly in your browser.
- Allows you to test your own
oauth_consumer_key
(your registered domain) and private key. - 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: |
|
Step 2: Modify OAuth Parameters and SettingsFor 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
Note: The In addition to Difference from AuthSub: |
|
Step 3-5: Acquire the access tokenThere 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.
|
|
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: Difference from AuthSub: Tip: Specifying a |
|
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
- 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.
- 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.
- Change the HTTP method dropdown to
PUT
. - Click "enter post data" below that dropdown and paste the
<entry>
XML into the popup. - 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.