OAuth in the Google Data Protocol Client Libraries
Stay organized with collections
Save and categorize content based on your preferences.
Page Summary
-
This document is about using Google Data API client libraries with OAuth Authentication for Web Applications, focusing on older APIs.
-
OAuth allows web applications to access Google services on behalf of a user securely by obtaining an access token without handling user login information.
-
The Google Data API client libraries provide methods to simplify the OAuth process for acquiring, authorizing, and exchanging tokens, as well as handling request signing.
-
To use OAuth, your web application must be registered with Google and all API calls need to be digitally signed using HMAC-SHA1 or RSA-SHA1.
-
This document provides detailed examples and code snippets for implementing 3-legged and 2-legged OAuth using Java, PHP, Python, and .NET client libraries, along with instructions for generating necessary keys and certificates.
Warning: This page is about Google's older APIs, the Google Data APIs; it's relevant only to the APIs that are listed in the Google Data APIs directory, many of which have been replaced with newer APIs. For information about a specific new API, see the new API's documentation. For information about authorizing requests with a newer API, see Google Accounts Authentication and Authorization.
This document describes how to use the Google Data API client libraries to connect to Google's OAuth Authentication for Web Applications.
The OAuth interface allows a web-based application to access a Google service on behalf of a user. To maintain a high level of security, OAuth enables the application to get an access token without ever handling the user's account login information.
The Google Data API client libraries provide methods to help you use OAuth in your web application. Specifically, there are methods for constructing the acquiring a request token, authorizing the request token, and exchanging the authorized request token for an access token. The libraries also handle the necessary signing algorithms when making requests to a Google Data service.
Audience
This document is intended for programmers who want their web-based applications to access Google services on behalf of users, using the Google Data APIs client libraries.
This document assumes that you are familiar with the OAuth interface and the general process for incorporating OAuth into your web application. For a complete description of OAuth's protocol, see OAuth Authentication for Web Applications or the official specification at oauth.net.
Using 3-legged OAuth and Google Data APIs without the client libraries
If you want your web application to interact with a Google Data service using OAuth as an authorization method, then everything you need to know is in OAuth Authentication for Web Applications. There's no need to use the Google Data APIs client libraries if you don't want to.
Here's an outline of how your application might authenticate a user using OAuth:
- Your application makes a signed request to fetch an initial OAuth request token from the
OAuthRequestTokenendpoint. - Your application redirects the user to the appropriate
OAuthAuthorizeTokenURL to authorize the request token. - Upon granting access, the user is redirected back to your application (the
oauth_callbackurl) - Your application sends a signed request to upgrade the authorized request token to an access token using the
OAuthGetAccessTokenendpoint.
The Google Data APIs client libraries simplify this authorization process by handling various details for you. This document explains how.
Registering your web application
OAuth requires that all API calls be digitally signed. Google supports the HMAC-SHA1 and RSA-SHA1 signature
methods. In order to sign requests, your application first needs to register with Google. Once you've registered, Google will provide
you with a consumer key (and secret for use with HMAC-SHA1), and a place to upload a public certificate.
1. Registering your domain
Please follow the steps outlined in Registration for Web-Based Applications.
2. Creating a private key / public certificate pair (optional)
If you choose to use RSA-SHA1 as the oauth_signature_method, you'll need to create a self-signing RSA
private key and public certificate pair. See Generating a self-signing private key and public certificate
(below) for examples on how to do that.
Working with 3-legged OAuth and the Google Data APIs: client library examples
The following sections show examples of using the Google Data APIs client library methods to follow the steps outlined in the
"Working With OAuth" section of the OAuth documentation. All examples in this document assume that your application host domain is example.com.
Determining the scope of your data access
Each Google service defines a scope value that determines a token's access to the user's data. The available scope values are listed in the Google Data FAQ. For example, to use the Documents List API, set the scope to https://docs.google.com/feeds/, as listed in the FAQ.
Note: Set the scope value to the narrowest URL that permits the access you need. This lessens the chance of accidentally obtaining and leaking personal data. For example, if you want to access the current user's private Document List feed, use the scope https://docs.google.com/feeds/default/private/full instead of a broader scope like https://docs.google.com/feeds/, which provides access to all Document List feeds.
Multi-scoped tokens
To create tokens that access multiple Google Data APIs, separate each scope with a space character. The example below creates a token with access to both a user's Google Documents and Google Calendar data.
scope=https://www.google.com/calendar/feeds/ https://docs.google.com/feeds/
URL-encoding
Non-ASCII characters that appear in URLs, including colon, slash, and space, must be URL-encoded in order to be transmitted via HTTP. Google Data API client libraries automatically URL-encode parameters for you, so you can simply use non-URL-encoded strings when assigning values to parameters. For example, you can make the following assignment in your code:
scope=https://www.google.com/calendar/feeds/ https://docs.google.com/feeds/
When you call the client library, the
scope parameter is then automatically URL-encoded to the following value:
https%3a%2f%2fwww.google.com%2fcalendar%2ffeeds%2f+https%3a%2f%2fdocs.google.com%2ffeeds%2f
Fetching a request token
Java
For HMAC-SHA1, you need some way to persist the token secret (obtained in the response) in order to create an OAuth token object coming back
from the approval page. To do that, set a session variable or cookie.
importcom.google.gdata.client.docs.* ; importcom.google.gdata.client.authn.oauth.* ; StringCONSUMER_KEY="example.com"; StringCONSUMER_SECRET="abc123doremi"; GoogleOAuthParametersoauthParameters=newGoogleOAuthParameters (); oauthParameters.setOAuthConsumerKey (CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret (CONSUMER_SECRET); oauthParameters.setScope ("https://docs.google.com/feeds/"); oauthParameters.setOAuthCallback ("http://www.example.com/UpgradeToken.jsp"); GoogleOAuthHelperoauthHelper=newGoogleOAuthHelper (newOAuthHmacSha1Signer ()); oauthHelper.getUnauthorizedRequestToken (oauthParameters);
Using RSA-SHA1, the oauth_token_secret is unused so there's no need to persist the token secret.
importcom.google.gdata.client.docs.* ; importcom.google.gdata.client.authn.oauth.* ; StringCONSUMER_KEY="example.com"; GoogleOAuthParametersoauthParameters=newGoogleOAuthParameters (); oauthParameters.setOAuthConsumerKey (CONSUMER_KEY); oauthParameters.setScope ("https://docs.google.com/feeds/"); oauthParameters.setOAuthCallback ("http://www.example.com/UpgradeToken.jsp"); PrivateKeyprivKey=getPrivateKey("/path/to/your/rsakey.pk8"); GoogleOAuthHelperoauthHelper=newGoogleOAuthHelper (newOAuthRsaSha1Signer (privKey)); oauthHelper.getUnauthorizedRequestToken (oauthParameters); ... publicstaticPrivateKeygetPrivateKey(StringprivKeyFileName){ FileprivKeyFile=newFile(privKeyFileName); FileInputStreamfis=newFileInputStream(privKeyFile); DataInputStreamdis=newDataInputStream(fis); byte[]privKeyBytes=newbyte[(int)privKeyFile.length()]; dis.read(privKeyBytes); dis.close(); fis.close(); StringBEGIN="-----BEGIN PRIVATE KEY-----"; StringEND="-----END PRIVATE KEY-----"; Stringstr=newString(privKeyBytes); if(str.contains(BEGIN)&&str.contains(END)){ str=str.substring(BEGIN.length(),str.lastIndexOf(END)); } KeyFactoryfac=KeyFactory.getInstance("RSA"); EncodedKeySpecprivKeySpec=newPKCS8EncodedKeySpec(Base64.decode(str)); returnfac.generatePrivate(privKeySpec); }
PHP
Using HMAC-SHA1 as the signature method:
require_once 'Zend/Oauth/Consumer.php'; session_start(); $CONSUMER_KEY = 'example.com'; $CONSUMER_SECRET = 'abc123doremi'; // Multi-scoped token. $SCOPES = array( 'https://docs.google.com/feeds/', 'https://spreadsheets.google.com/feeds/' ); $oauthOptions = array( 'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER, 'version' => '1.0', 'consumerKey' => $CONSUMER_KEY, 'consumerSecret' => $CONSUMER_SECRET, 'signatureMethod' => 'HMAC-SHA1', 'callbackUrl' => 'http://myapp.example.com/access_token.php', 'requestTokenUrl' => 'https://www.google.com/accounts/OAuthGetRequestToken', 'userAuthorizationUrl' => 'https://www.google.com/accounts/OAuthAuthorizeToken', 'accessTokenUrl' => 'https://www.google.com/accounts/OAuthGetAccessToken' ); $consumer = new Zend_Oauth_Consumer($oauthOptions); // When using HMAC-SHA1, you need to persist the request token in some way. // This is because you'll need the request token's token secret when upgrading // to an access token later on. The example below saves the token object as a session variable. if (!isset($_SESSION['ACCESS_TOKEN'])) { $_SESSION['REQUEST_TOKEN'] = serialize($consumer->getRequestToken(array('scope' => implode(' ', $SCOPES)))); }
Using RSA-SHA1 as the signature method:
require_once 'Zend/Crypt/Rsa/Key/Private.php'; require_once 'Zend/Oauth/Consumer.php'; session_start(); $CONSUMER_KEY = 'example.com'; $SCOPE = 'https://docs.google.com/feeds/'; $oauthOptions = array( 'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER, 'version' => '1.0', 'consumerKey' => $CONSUMER_KEY, 'consumerSecret' => new Zend_Crypt_Rsa_Key_Private(file_get_contents(realpath('/path/to/yourRSAPrivateKey.pem'))), 'signatureMethod' => 'RSA-SHA1', 'callbackUrl' => 'http://myapp.example.com/access_token.php', 'requestTokenUrl' => 'https://www.google.com/accounts/OAuthGetRequestToken', 'userAuthorizationUrl' => 'https://www.google.com/accounts/OAuthAuthorizeToken', 'accessTokenUrl' => 'https://www.google.com/accounts/OAuthGetAccessToken' ); $consumer = new Zend_Oauth_Consumer($oauthOptions); if (!isset($_SESSION['ACCESS_TOKEN'])) { $_SESSION['REQUEST_TOKEN'] = serialize($consumer->getRequestToken(array('scope' => $SCOPE))); }
Python
Using HMAC-SHA1 as the signature method:
If you're using the newer v2.0+ classes based on GDClient, use:
importgdata.gauth importgdata.docs.client CONSUMER_KEY = 'example.com' CONSUMER_SECRET = 'abc123doremi' SCOPES = ['https://docs.google.com/feeds/', 'https://www.google.com/calendar/feeds/'] # example of a multi-scoped token client = gdata.docs.client.DocsClient(source='yourCompany-YourAppName-v1') oauth_callback_url = 'http://%s/get_access_token' % self.request.host request_token = client.GetOAuthToken( SCOPES, oauth_callback_url, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET) # When using HMAC-SHA1, you need to persist the request_token in some way. # You'll need the token secret when upgrading to an access token later on. # In Google App Engine, you can use the AeSave helper: # gdata.gauth.AeSave(request_token, 'myKey')
Using RSA-SHA1 as the signature method:
... f = open('/path/to/yourRSAPrivateKey.pem') RSA_KEY = f.read() f.close() request_token = client.GetOAuthToken(SCOPES, oauth_callback_url, CONSUMER_KEY, rsa_private_key=RSA_KEY)
Alternatively, if you're using the older v1.0 classes based on GDataService, the calls are a bit different:
importgdata.auth importgdata.docs.service CONSUMER_KEY = 'example.com' CONSUMER_SECRET = 'abc123doremi' client = gdata.docs.service.DocsService (source='yourCompany-YourAppName-v1') client.SetOAuthInputParameters (gdata.auth.OAuthSignatureMethod .HMAC_SHA1, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET) req_token = client.FetchOAuthRequestToken () client.SetOAuthToken (req_token)
Using RSA-SHA1 as the signature method:
... f = open('/path/to/yourRSAPrivateKey.pem') RSA_KEY = f.read() f.close() client = gdata.docs.service.DocsService (source='yourCompany-YourAppName-v1') client.SetOAuthInputParameters (gdata.auth.OAuthSignatureMethod .RSA_SHA1, CONSUMER_KEY, rsa_key=RSA_KEY) SCOPES = ['https://docs.google.com/feeds/', 'https://www.google.com/calendar/feeds/'] # example of a multi-scoped token req_token = client.FetchOAuthRequestToken (scopes=SCOPES) client.SetOAuthToken (req_token)
.NET
Using HMAC-SHA1 as the signature method:
usingGoogle.GData.Client; stringCONSUMER_KEY="example.com"; stringCONSUMER_SECRET="abc123doremi"; //Multi-scopedtoken. stringSCOPE="https://www.google.com/calendar/feeds/ https://www.google.com/m8/feeds/"; OAuthParametersparameters=newOAuthParameters(){ ConsumerKey=CONSUMER_KEY, ConsumerSecret=CONSUMER_SECRET, Scope=SCOPE, Callback="http://myapp.example.com/access_token", SignatureMethod = "HMAC-SHA1" } OAuthUtil.GetUnauthorizedRequestToken(parameters);
Using RSA-SHA1 as the signature method:
RSA-SHA1 is not supported yet.
Authorizing a request token
To authorize a request token, your application must redirect the user to the OAuthAuthorizeToken URL, which prompts them to log into their Google account.
For more information on the OAuthAuthorizeToken URL, see the
full OAuth Authentication for Web Applications.
To construct the OAuthAuthorizeToken URL in your application, use the following for each client library. Note, these
samples build on the previous examples.
After constructing the approval page URL, your application can use it in a variety of ways to send the user to the
OAuthAuthorizeToken handler. The most common approach is to redirect the user or display a link to that page.
Java
For HMAC-SHA1:
StringapprovalPageUrl=oauthHelper.createUserAuthorizationUrl (oauthParameters); System.out.println(approvalPageUrl);
For RSA-SHA1:
StringapprovalPageUrl=oauthHelper.createUserAuthorizationUrl (oauthParameters); System.out.println(approvalPageUrl);
PHP
// If on a G Suite domain, use your domain for the hd param (e.g. 'example.com'). $approvalUrl = $consumer->getRedirectUrl(array('hd' => 'default')); echo "<a href=\"$approvalUrl\">Grant access</a>";
Alternatively, you can simply redirect to the approval URL:
// If on a G Suite domain, use your domain for the hd param (e.g. 'example.com'). $consumer->redirect(array('hd' => 'default'));
Python
If you're using the newer v2.0+ classes based on GDClient, use:
# req_token is from previous call to client.GetOAuthToken() domain = None # If on a G Suite domain, use your domain (e.g. 'example.com'). self.redirect(request_token.generate_authorization_url(google_apps_domain=domain))
If you're using the older v1.0 classes based on GDataService, the process is a bit different.
# req_token is from previous call to client.FetchOAuthRequestToken() oauth_callback_url = 'http://%s/get_access_token' % self.request.host self.redirect(client.GenerateOAuthAuthorizationURL (callback_url=oauth_callback_url))
.NET
string authorizationUrl = OAuthUtil.CreateUserAuthorizationUrl(parameters); Console.WriteLine(authorizationUrl);
Extracting the token from the callback URL
When Google redirects back to your application, the oauth_token is appended to the "oauth_callback_url" URL as a query parameter.
Your application should then extract the token value from its URL query parameter and re-establish the oauth parameters.
The client libraries provide convenience methods for extracting the oauth_token. These samples build on the previous examples.
Java
If you've chosen to persist the token secret in the callback URL (when using HMAC-SHA1):
GoogleOAuthParametersoauthParameters=newGoogleOAuthParameters (); oauthParameters.setOAuthConsumerKey (CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret (CONSUMER_SECRET); GoogleOAuthHelperoauthHelper=newGoogleOAuthHelper (newOAuthHmacSha1Signer ()); oauthHelper.getOAuthParametersFromCallback (request.getQueryString(),oauthParameters);
The only difference with RSA-SHA1 is the signing method:
GoogleOAuthParametersoauthParameters=newGoogleOAuthParameters (); oauthParameters.setOAuthConsumerKey (CONSUMER_KEY); PrivateKeyprivKey=getPrivateKey("/path/to/your/rsakey.pk8"); GoogleOAuthHelperoauthHelper=newGoogleOAuthHelper (newOAuthRsaSha1Signer (privKey)); oauthHelper.getOAuthParametersFromCallback (request.getQueryString(),oauthParameters);
PHP
This step isn't necessary when using the PHP library.
Python
If you're using the newer v2.0+ classes based on GDClient, use:
# Recall request_token. In Google App Engine, use AeLoad(): # saved_request_token = gdata.gauth.AeLoad('myKey') request_token = gdata.gauth.AuthorizeRequestToken(saved_request_token, self.request.uri)
If you're using the older v1.0 classes based on GDataService, use:
oauth_token = gdata.auth.OAuthTokenFromUrl (self.request.uri) if oauth_token: oauth_token.secret = # TODO: recall saved request_token and set the token secret here. oauth_token.oauth_input_params = gdata.auth.OAuthInputParams ( gdata.auth.OAuthSignatureMethod .HMAC_SHA1, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET) client.SetOAuthToken (oauth_token) else: print 'No oauth_token found in the URL'
The process is similar for RSA-SHA1, but without the token secret:
oauth_token = gdata.auth.OAuthTokenFromUrl (self.request.uri) if oauth_token: oauth_token.oauth_input_params = gdata.auth.OAuthInputParams ( gdata.auth.OAuthSignatureMethod .RSA_SHA1, CONSUMER_KEY, rsa_key=RSA_KEY) client.SetOAuthToken (oauth_token) else: print 'No oauth_token found in the URL'
.NET
If you've chosen to persist the token secret in the callback URL:
OAuthUtil.UpdateOAuthParametersFromCallback(url, parameters);
Upgrading to an access token
The last step in the OAuth token dance is to upgrade the authorized request token to a long-lived access token using the
OAuthGetAccessToken URL, as described
in the full OAuth Authentication for Web Applications documentation.
Here are some examples using each of the client libraries:
Java
StringaccessToken=oauthHelper.getAccessToken (oauthParameters); // You can also pull the OAuth token string from the oauthParameters: // String accessToken = oauthParameters.getOAuthToken(); System.out.println("OAuth Access Token: "+accessToken); StringaccessTokenSecret=oauthParameters.getOAuthTokenSecret (); System.out.println("OAuth Access Token's Secret: "+accessTokenSecret);
PHP
if (!isset($_SESSION['ACCESS_TOKEN'])) { if (!empty($_GET) && isset($_SESSION['REQUEST_TOKEN'])) { $_SESSION['ACCESS_TOKEN'] = serialize($consumer->getAccessToken($_GET, unserialize($_SESSION['REQUEST_TOKEN']))); } }
Python
If you're using the newer v2.0+ classes based on GDClient, use:
# Upgrade the token and save in the user's datastore access_token = client.GetAccessToken(request_token) # If you're using Google App Engine, you can call the AeSave() method to save # the access token under the current logged in user's account. #gdata.gauth.AeSave(access_token, token_key)
If you're using the older v1.0 classes based on GDataService, use:
access_token = client.UpgradeToOAuthAccessToken () # calls SetOAuthToken() for you
If you're using gdata.gauth.AeSave() on App Engine, the token and token secret will be stored for you under the current logged in user.
.NET
OAuthUtil.GetAccessToken(parameters); //IfyouwanttoextracttheOAuthToken/TokenSecretfromtheOAuthParametersinstance: stringaccessToken=parameter.Token; Console.WriteLine("OAuth Access Token: "+accessToken); stringaccessTokenSecret=parameter.TokenSecret; Console.WriteLine("OAuth Access Token's Secret: "+accessTokenSecret);
Note: If you're using HMAC-SHA1, be sure to save the access token's token secret
alongside the token value in your database, otherwise you won't be able to properly reconstruct the oauth parameters for later use.
Using an access token
After you've obtained an access token, use the standard Google Data APIs client library calls to interact with the service. The library will take care of signing the requests and including the correct Authorization header for you. Typically, you'll be recalling the user's token from a cookie or database. These examples demonstrate how to reconstruct the oauth parameters and make a client library call.
Java
If you're using HMAC-SHA1:
GoogleOAuthParametersoauthParameters=newGoogleOAuthParameters (); oauthParameters.setOAuthConsumerKey (CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret (CONSUMER_SECRET); oauthParameters.setOAuthToken (ACCESS_TOKEN); oauthParameters.setOAuthTokenSecret (TOKEN_SECRET); DocsServiceclient=newDocsService ("yourCompany-YourAppName-v1"); client.setOAuthCredentials (oauthParameters,newOAuthHmacSha1Signer ()); URLfeedUrl=newURL("https://docs.google.com/feeds/default/private/full"); DocumentListFeedresultFeed=client.getFeed(feedUrl,DocumentListFeed.class); for(DocumentListEntryentry:resultFeed.getEntries()){ System.out.println(entry.getTitle().getPlainText()); }
The difference with RSA-SHA1 is that you don't need to set the access token's secret and constructing the signer object is different:
GoogleOAuthParametersoauthParameters=newGoogleOAuthParameters (); oauthParameters.setOAuthConsumerKey (CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret (CONSUMER_SECRET); oauthParameters.setOAuthToken (ACCESS_TOKEN); PrivateKeyprivKey=getPrivateKey("/path/to/your/rsakey.pk8");// See above for the defintion of getPrivateKey() DocsServiceclient=newDocsService ("yourCompany-YourAppName-v1"); client.setOAuthCredentials (oauthParameters,newOAuthRsaSha1Signer (privKey)); URLfeedUrl=newURL("https://docs.google.com/feeds/default/private/full"); DocumentListFeedresultFeed=client.getFeed(feedUrl,DocumentListFeed.class); for(DocumentListEntryentry:resultFeed.getEntries()){ System.out.println(entry.getTitle().getPlainText()); }
PHP
require_once 'Zend/Gdata/Docs.php'; if (isset($_SESSION['ACCESS_TOKEN'])) { $accessToken = unserialize($_SESSION['ACCESS_TOKEN']); } else { exit; } /* Or, you could set an existing token (say one stored from your database). For HMAC-SHA1: $accessToken = new Zend_Oauth_Token_Access(); $accessToken->setToken('1/AQfoI-qJDqkvvkf216Gc2g'); $accessToken->setTokenSecret('2c26GLW250tZiQ'); */ $httpClient = $accessToken->getHttpClient($oauthOptions); $client = new Zend_Gdata_Docs($httpClient, "yourCompany-YourAppName-v1"); // Retrieve user's list of Google Docs $feed = $client->getDocumentListFeed(); foreach ($feed->entries as $entry) { echo "$entry->title\n"; }
Python
This snippet assumes that you have already fetched an access token (using HMAC-SHA1) and
are recalling that token key/secret for later use.
If you're using the newer v2.0+ classes based on GDClient, use:
client = gdata.docs.client.DocsClient(source='yourCo-yourAppName-v1') client.auth_token = gdata.gauth.OAuthHmacToken(CONSUMER_KEY, CONSUMER_SECRET, TOKEN, TOKEN_SECRET, gdata.gauth.ACCESS_TOKEN) feed = client.GetDocList () for entry in feed.entry: print entry.title.text
If you're using the older v1.0 classes based on GDataService, use:
client = gdata.docs.service.DocsService (source='yourCompany-YourAppName-v1') client.SetOAuthInputParameters (SIG_METHOD, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET) # the token key and secret should be recalled from your database client.SetOAuthToken(gdata.auth.OAuthToken(key=TOKEN, secret=TOKEN_SECRET)) feed = client.GetDocumentListFeed () for entry in feed.entry: print entry.title.text
.NET
If you're using HMAC-SHA1:
OAuthParameters parameters = new OAuthParameters() {
ConsumerKey = CONSUMER_KEY,
ConsumerSecret = CONSUMER_SECRET,
Token = ACCESS_TOKEN,
TokenSecret = TOKEN_SECRET
}
GOAuthRequestFactory requestFactory = new GOAuthRequestFactory("writely", APPLICATION_NAME, parameters);
DocsService service = new DocsService(APPLICATION_NAME);
service.RequestFactory = requestFactory;
DocumentsListQuery query = new DocumentsListQuery();
DocumentsFeed feed = service.Query(query);
foreach (DocumentEntry entry in feed.Entries) {
Console.WriteLine(entry.Title.Text);
}The difference with RSA-SHA1 is that you don't need to set the access token's secret and constructing the signer object is different:
RSA-SHA1 is not supported yet.
Additional 3-Legged OAuth Resources and Samples
- OAuth examples on the Google Data API Tips Blog
- Article: Using OAuth with the Google Data APIs
- Python client library sample
- Python client library Google App Engine sample
- Java client library sample
- Java client library Google App Engine sample
- Zend PHP client library sample
- OAuth Authentication for Web Applications documentation
- OAuth.net documentation
2 Legged OAuth
2 legged OAuth allows trusted applications to access users' Google Data without their direct involvement. Two key groups can use two-legged OAuth:
G Suite domain administrators: Administrators can build scripts and custom applications that manage the user data for their domain through Google Data APIs. To learn about managing the key and secret that's associated with your G Suite domain, and granting global access control, see "Managing the OAuth key and secret".
Third-party software vendors: Vendors may offer applications that use two-legged OAuth to integrate with G Suite. Access for the 3rd party applications can be granted on the Manage API client page or by installing from the G Suite Marketplace.
An access token is not required as per the normal authorization flow (also referred to as 3-legged OAuth).
The following client library samples demonstrate how to setup your client to use 2 Legged OAuth using HMAC-SHA1.
Java
importcom.google.gdata.client.docs.* ; importcom.google.gdata.client.authn.oauth.* ; StringCONSUMER_KEY="example.com"; StringCONSUMER_SECRET="abc123doremi"; GoogleOAuthParametersoauthParameters=newGoogleOAuthParameters (); oauthParameters.setOAuthConsumerKey (CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret (CONSUMER_SECRET); DocsServiceclient=newDocsService ("yourCompany-YourAppName-v1"); client.setOAuthCredentials (oauthParameters,newOAuthHmacSha1Signer ()); // Retrieve user's list of Google Docs Stringuser="any.user@anydomain.com"; URLfeedUrl=newURL("https://docs.google.com/feeds/default/private/full"+ "?xoauth_requestor_id="+user); DocumentListFeedresultFeed=client.getFeed(feedUrl,DocumentListFeed.class); for(DocumentListEntryentry:resultFeed.getEntries()){ System.out.println(entry.getTitle().getPlainText()); }
PHP
require_once 'Zend/Oauth/Consumer.php'; require_once 'Zend/Gdata/Docs.php'; $CONSUMER_KEY = 'example.com'; $CONSUMER_SECRET = 'abc123doremi'; $USER = 'any.user@anydomain.com'; $oauthOptions = array( 'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER, 'version' => '1.0', 'signatureMethod' => 'HMAC-SHA1', 'consumerKey' => $CONSUMER_KEY, 'consumerSecret' => $CONSUMER_SECRET ); $consumer = new Zend_Oauth_Consumer($oauthOptions); $token = new Zend_Oauth_Token_Access(); $httpClient = $token->getHttpClient($oauthOptions); $client = new Zend_Gdata_Docs($httpClient); // Retrieve user's list of Google Docs $feed = $client->getDocumentListFeed('https://docs.google.com/feeds/default/private/full?xoauth_requestor_id=' . urlencode($USER)); foreach ($feed->entries as $entry) { echo "$entry->title\n"; }
Python
If you're using the newer v2.0+ classes based on GDClient, use:
importgdata.gauth importgdata.docs.client CONSUMER_KEY = 'example.com' CONSUMER_SECRET = 'abc123doremi' requestor_id = 'any.user@anydomain.com' client = gdata.docs.client.DocsClient(source='yourCompany-YourAppName-v1') client.auth_token = gdata.gauth.TwoLeggedOAuthHmacToken( CONSUMER_KEY, CONSUMER_SECRET, requestor_id) # Retrieve user's list of Google Docs feed = client.GetDocList() for entry in feed.entry: print entry.title.text
If you're using the older v1.0 classes based on GDataService, use:
importgdata.auth importgdata.docs.service CONSUMER_KEY = 'example.com' CONSUMER_SECRET = 'abc123doremi' SIG_METHOD = gdata.auth.OAuthSignatureMethod .HMAC_SHA1 requestor_id = 'any.user@anydomain.com' client = gdata.docs.service.DocsService (source='yourCompany-YourAppName-v1') client.SetOAuthInputParameters (SIG_METHOD, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET, two_legged_oauth=True, requestor_id=requestor_id) # Retrieve user's list of Google Docs feed = client.GetDocumentListFeed () for entry in feed.entry: print entry.title.text # Change to another user on your domain client.GetOAuthInputParameters ().requestor_id = 'another.user@example.com'
.NET
usingGoogle.GData.Client ; usingGoogle.GData.Documents ; //CreateanOAuthfactorytouse GOAuthRequestFactoryrequestFactory=newGOAuthRequestFactory ("writely","yourCompany-YourAppName-v1"); requestFactory.ConsumerKey="example.com"; requestFactory.ConsumerSecret="abc123doremi"; Stringuser="any.user@anydomain.com"; DocumentsServiceclient=newDocumentsService ("yourCompany-YourAppName-v1"); client.RequestFactory=requestFactory; //Retrieveuser'slistofGoogleDocs DocumentsListQueryquery=newDocumentsListQuery (); query.Uri=newOAuthUri("https://docs.google.com/feeds/default/private/full",user,requestFactory.ConsumerKey); DocumentsFeed feed=client.Query(query); foreach(DocumentEntry entryinfeed.Entries) { Console.WriteLine(entry.Title.Text); }
Additional 2-Legged OAuth Resources and Samples
- 2 legged OAuth examples on the Google Data API Tips Blog
- Java client library 2-Legged OAuth sample
- Python client library TwoLeggedOAuthExample (for client.py classes) or 2_legged_oauth sample (for service.py classes)
- .NET client library 2-Legged OAuth sample
- 2 legged OAuth documentation
Generating a self-signing private key and public certificate
The private key is used to generate a signature, which must be included with each request. The public key embedded in the certificate is used by Google to verify the signature. The public key must be a 1024-bit RSA key encoded in an X.509 certificate in PEM format. The certificate should be sent to Google at time of registration.
The following sections provide examples of how to generate keys and certificates using two particular tools: the OpenSSL utility and Java's keytool utility.
These examples are not specific to the Google Data APIs; you can use the same utilities to generate keys for any purpose.
The examples assume that your company is named My_Company, and is located in Mountain View, California, US, with domain name example.com.
Generating keys using OpenSSL
To create a pair of RSA keys and the corresponding certificate, you could use the following command:
# Generate the RSA keys and certificate openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj \ '/C=US/ST=CA/L=Mountain View/CN=www.example.com' -keyout \ myrsakey.pem -out /tmp/myrsacert.pem
Warning: Including the -nodes parameter creates a private key without a password to protect it.
However, you should consider omitting this parameter for added security.
The -sha1 parameter specifies that the key will be used to generate SHA1 signatures.
The -subj parameter specifies the identity of the application that the certificate represents.
The -keyout parameter specifies the file that will contain the keys.
This file contains sensitive information and should be protected and not shared with anyone.
The -out parameter specifies the file that will contain the certificate in PEM format
(which can be sent to Google while registering).
Generating keys for the .NET client
The .NET framework doesn't understand keys or certificates stored in the PEM format. Therefore, an additional step is needed once you have created the .pem file:
opensslpkcs12-export-intest_cert.pem-inkeymyrsacert.pem-outmyrsacert.pfx-name"Testing Certificate"
This step generates a PFX file from your private key and certificate. This file can be imported into the .NET client library to digitally sign requests made to the Google Data APIs.
Generating keys for the Java client
The Java client accepts private keys in the PKCS#8 format. After generating a key/cert using the directions above, create a .pk8 file from your generated .pem file:
openssl pkcs8 -in myrsakey.pem -topk8 -nocrypt -out myrsakey.pk8
Alternatively, you can use the Java key store and the keytool utility to create a pair of RSA keys and the corresponding certificate. Use the following command:
# Generate the RSA keys and certificate keytool-genkey-v-aliasExample-keystore./Example.jks\ -keyalgRSA-sigalgSHA1withRSA\ -dname"CN=www.example.com, OU=Engineering, O=My_Company, L=Mountain View, ST=CA, C=US"\ -storepasschangeme-keypasschangeme
Warning: "changeme" is not a good password; this is just an example.
The -dname parameter specifies the identity of the application that the certificate represents. The -storepass parameter specifies the password to protect the keystore. The -keypass parameter specifies the password to protect the private key.
To write the certificate to a file that can be used in the ManageDomains tool, use the following command:
# Output the public certificate to a file keytool-export-rfc-keystore./Example.jks-storepasschangeme\ -aliasExample-filemycert.pem