This document describes how to use Google's Authentication for Installed Applications within each of the Google Data API client libraries.
Installed applications that need to access to a user's private data (protected by a Google or Google Apps (hosted) account), can use ClientLogin as programmatic means for authenticating users. An "installed application" is one that is installed on a device, such as a desktop computer or a cell phone, as opposed to a web application.
It is discouraged for web applications to use ClientLogin as their authentication method. Instead, please see Using AuthSub with the Google Data API Client Libraries.
This document is intended for developers who want to write applications that access a Google Data service using the Google Data APIs client libraries. This document assumes that you are familiar with the ClientLogin interface. For a complete description of ClientLogin's protocol, see Authentication for Installed Applications.
The Google Data API client libraries provide methods to help you use ClientLogin in your applications. Specifically, there are methods for
acquiring an authentication token, handling CAPTCHA challenges, recalling the auth token for later use, and sending the correct Authorization header with
every request.
The client libraries are by no means the only way to use ClientLogin in your applications. Everything you need to know can be found in the ClientLogin documentation, Authentication for Installed Applications. However, the client libraries provide helpful methods for utilizing ClientLogin in your Google Data application.
This section gives examples of using the Google Data APIs client libraries to follow the steps outlined in the "The ClientLogin Interface" section of the ClientLogin documentation.
The examples throughout this document demonstrate interacting with Google Calendar (although you don't need to know anything about the Calendar Data API to follow the examples).
To use ClientLogin, your application should make an HTTPS POST to the handler ClientLogin's handler
https://www.google.com/accounts/ClientLogin. The POST body should be structured
as a form post with the default encoding application/x-www-form-urlencoded. Using one of client libraries, you
can make this request in a single line of code.
The following samples first setup a service object connecting to the Calendar Data API, and then make an HTTP POST
to the ClientLogin handler.
import com.google.gdata.client.*; import com.google.gdata.client.calendar.*; CalendarService client = new CalendarService("yourCompany-yourAppName-v1"); client.setUserCredentials("user@example.com", "pa$$word");
If you know your users will be using a Google Apps hosted account (as opposed to a Google/Gmail Account), you can streamline the login process by
specifying the appropriate ClientLogin accountType:
import com.google.gdata.client.*; import com.google.gdata.client.calendar.*; CalendarService client = new CalendarService("yourCompany-yourAppName-v1"); client.setUserCredentials("user@example.com", "pa$$word", ClientLoginAccountType.HOSTED);
using Google.GData.Client; using Google.GData.Calendar; CalendarService client = new CalendarService("yourCompany-yourAppName-v1"); client.setUserCredentials("user@example.com", "pa$$word"); client.QueryAuthenticationToken(); // Authenticate the user immediately
If you know your users will be using a Google Apps hosted account (as opposed to a Google/Gmail Account), you can streamline the login process by
specifying the appropriate ClientLogin accountType:
using Google.GData.Client; using Google.GData.Calendar; GDataGAuthRequestFactory authFactory = new GDataGAuthRequestFactory("cl", "yourCompany-yourAppName-v1"); authFactory.AccountType = "HOSTED"; CalendarService client = new CalendarService(authFactory.ApplicationName); client.RequestFactory = authFactory; client.setUserCredentials("user@example.com", "pa$$word"); client.QueryAuthenticationToken(); // Authenticate the user immediately
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');
$serviceName = Zend_Gdata_Calendar::AUTH_SERVICE_NAME; // predefined service name ('cl') for calendar
$applicationName = 'yourCompany-yourAppName-v1';
// Create an authenticated HTTP client
$httpClient = Zend_Gdata_ClientLogin::getHttpClient('user@example.com', 'pa$$word', $serviceName, null, $applicationName);
$client = new Zend_Gdata_Calendar($httpClient, $applicationName); // Create an instance of the Calendar service
If you know your users will be using a Google Apps hosted account (as opposed to a Google/Gmail Account), you can streamline the login process by
specifying the appropriate ClientLogin accountType:
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');
$serviceName = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
$applicationName = 'yourCompany-yourAppName-v1';
$accountType = 'HOSTED';
$httpClient = Zend_Gdata_ClientLogin::getHttpClient(
'user@example.com', 'pa$$word', $serviceName, null, $applicationName, null, null, null, $accountType);
$client = new Zend_Gdata_Calendar($httpClient, $applicationName);
import gdata.calendar.service email = 'user@example.com' password = 'pa$$word' application_name = 'yourCompany-yourAppName-v1' client = gdata.calendar.service.CalendarService() client.ClientLogin(email, password, source=application_name) # OR, you can use ProgrammaticLogin() client = gdata.calendar.service.CalendarService(email=email, password=password, source=application_name) client.ProgrammaticLogin()
If you know your users will be using a Google Apps hosted account (as opposed to a Google/Gmail Account), you can streamline the login process by
specifying the appropriate ClientLogin accountType:
import gdata.calendar.service client = gdata.calendar.service.CalendarService() client.ClientLogin('user@example.com', 'pa$$word', account_type='HOSTED', source='yourCompany-yourAppName-v1')
See the request parameters section for a
detailed explanation of each ClientLogin parameter. A complete list of available service names is available in the FAQ.
Note: By default, the client libraries set the accountType parameter is set to
HOSTED_OR_GOOGLE. That means ClientLogin will first try to authenticate the user's credentials as a Google Apps hosted account. If that fails,
it will try to authenticate as a Google Account. This becomes tricky if user@example.com is both a Google Account and a Google Apps account.
In that special case, set accountType=GOOGLE if the user wishes to use the Google Accounts version of user@example.com.
Once the login information has been successfully authenticated, Google returns a token, which your application will reference each time
it requests access to the user's account, such as to GET or POST data. The token remains valid for a set length of time,
defined by whichever Google service you're working with. Typically, tokens remain valid for 2 weeks.
After your application has authenticated the user once, there's no need for them to input their credentials again.
We recommend storing the Auth token in your database and recalling it as necessary. That will save the overhead of an additional
HTTPS POST and a possible CAPTCHA challenge.
The libraries provide getters/setters for accessing the token:
String token = '12345abcde'; // TODO: Read user's token from your database client.setUserToken(token); UserToken auth_token = (UserToken) client.getAuthTokenFactory().getAuthToken(); token = auth_token.getValue(); // token is '12345abcde'
String token = '12345abcde'; // TODO: Read user's token from your database client.SetAuthenticationToken(token); GDataGAuthRequestFactory requestFactory = (GDataGAuthRequestFactory) client.RequestFactory; token = requestFactory.GAuthToken; // token is '12345abcde'
$token = '12345abcde'; // TODO: Read user's token from your database $client->getHttpClient()->setClientLoginToken($token); $token = $client->getHttpClient()->getClientLoginToken(); // $token is '12345abcde'
token = '12345abcde' # TODO: Read user's token from your database client.SetClientLoginToken(token) token = client.GetClientLoginToken() # token is '12345abcde'
A failure response from ClientLogin contains an error code and a URL to an error page that can be displayed to the user. If the error code is a CAPTCHA challenge, the response also includes a URL to a CAPTCHA image and a special token. Your application should be able to solicit an answer from the user and then retry the login request.
String email = "user@example.com";
String password = "pa$$word";
try {
client.setUserCredentials(email, password);
} catch (CaptchaRequiredException e) {
System.out.println("Please visit " + e.getCaptchaUrl());
System.out.print("Answer to the challenge? ");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String answer = in.readLine();
service.setUserCredentials(email, password, e.getCaptchaToken(), answer);
} catch (AuthenticationException e) {
System.out.println(e.getMessage());
}
try
{
client.setUserCredentials("user@example.com", "pa$$word");
client.QueryAuthenticationToken(); // Authenticate the user immediately
}
catch (CaptchaRequiredException e)
{
Console.WriteLine("Please visit " + e.Url);
Console.Write("Answer to the challenge? ");
String answer = Console.ReadLine();
GDataGAuthRequestFactory requestFactory = (GDataGAuthRequestFactory) client.RequestFactory;
requestFactory.CaptchaAnswer = answer;
requestFactory.CaptchaToken = e.Token;
client.QueryAuthenticationToken(); // authenticate the user again
}
catch (InvalidCredentialsException e)
{
Console.WriteLine(e.Message);
}
catch (AuthenticationException e)
{
Console.WriteLine(e.Message);
}
$email = 'user@example.com';
$password = 'pa$$word';
$serviceName = 'cl'; // 'cl' is the service name for the Calendar API
$appName = 'yourCompany-yourAppName-v1';
try {
$httpClient = Zend_Gdata_ClientLogin::getHttpClient($email, $password, $serviceName, null, $appName);
} catch (Zend_Gdata_App_CaptchaRequiredException $e) {
echo '<a href="' . $e->getCaptchaUrl() . '">CAPTCHA answer required to login</a>';
$answer = 'Your answer to the challenge';
$httpClient = Zend_Gdata_ClientLogin::getHttpClient(
$email, $password, $serviceName, null, $appName, $e->getCaptchaToken(), $answer);
} catch (Zend_Gdata_App_AuthException $e) {
echo 'Error: ' . $e->getMessage();
if ($e->getResponse() != null) {
echo 'Body: ' . $e->getResponse()->getBody();
}
}
import gdata.service email = 'user@example.com' password = 'pa$$word' application_name = 'yourCompany-yourAppName-v1' try: client.ClientLogin(email, password, source=application_name) except gdata.service.CaptchaRequired: print 'Please visit ' + client.captcha_url answer = raw_input('Answer to the challenge? ') client.ClientLogin(email, password, source=application_name, captcha_token=client.captcha_token, captcha_response=answer) except gdata.service.BadAuthentication: exit('Users credentials were unrecognized') except gdata.service.Error: exit('Login Error')
For more information on CAPTCHAs, see the ClientLogin Response section of the "Authentication for Installed Applications" documentation.