Google Data Protocol 用戶端程式庫中的 ClientLogin

警告:本頁面說明 Google 的舊版 API (即 Google Data API);該 API 只與 Google Data API 目錄中列出的 API 相關,其中許多 API 已由新版 API 取代。如需特定新的 API 的相關資訊,請參閱新 API 的說明文件。如要瞭解如何使用新版 API 授權要求,請參閱 Google 帳戶驗證與授權

重要事項:請勿使用 ClientLogin 來處理新的應用程式。請改用更安全的 OAuth 驗證通訊協定。ClientLogin 是一種已淘汰的驗證通訊協定,並已於 2015 年 4 月 20 日停用。屆時,系統將不再回應 ClientLogin 要求。如果您目前使用 ClientLogin 的應用程式,建議您改用 OAuth。下一個程式庫將停止支援這個程式庫中的 ClientLogin 支援。

本文件說明如何在每個 Google Data API 用戶端程式庫中使用 Google 的已安裝應用程式驗證

已安裝的應用程式需要存取使用者的私人資料 (受到 Google 或 G Suite 帳戶保護),則可以將 ClientLogin 當做程式輔助使用者進行驗證。「已安裝的應用程式」是在裝置上安裝 (例如桌上型電腦或手機),而不是與網路應用程式安裝的應用程式。

要建立網路應用程式嗎?

不讓網路應用程式使用 ClientLogin 做為驗證方法。請改為參閱搭配 Google Data API 用戶端程式庫使用 AuthSub

目標對象

本文件的適用對象,是想使用 Google Data API 用戶端程式庫編寫存取 Google Data 服務的應用程式。這份文件假設您已熟悉 ClientLogin 介面。如需 ClientLogin 通訊協定的完整說明,請參閱安裝版應用程式驗證

Google Data API 用戶端程式庫提供方法,可協助您在應用程式中使用 ClientLogin。具體來說,有幾種方法可以取得驗證權杖、處理人機驗證 (Captcha) 驗證、喚回驗證權杖以供日後使用,並在每個要求中傳送正確的 Authorization 標頭。

在沒有用戶端程式庫的情況下使用 ClientLogin 和 Google Data API

用戶端程式庫是您在應用程式中使用 ClientLogin 的唯一方法。您需要的所有資訊都位於 ClientLogin 說明文件中,適用於已安裝應用程式的驗證。不過,用戶端程式庫提供了在 Google Data 應用程式中利用 ClientLogin 的實用方法。

使用 ClientLogin 和 Google Data API:用戶端程式庫範例

本節提供 Google Data API 用戶端程式庫的使用範例,以遵循 ClientLogin 說明文件中「ClientLogin Interface」(用戶端登入介面) 一節所述的步驟。

本文件中的範例示範瞭如何與「Google 日曆」互動 (雖然您不需要知道 Calendar Data API 的操作範例即可)。

取得驗證權杖

如要使用 ClientLogin,您的應用程式應將 HTTPS POST 傳送至處理常式 ClientLogin 的處理常式 https://www.google.com/accounts/ClientLoginPOST 主體的結構應為採用預設編碼 application/x-www-form-urlencoded 的表單訊息。您可以透過其中一個用戶端程式庫,在單行程式碼中發出這項要求。

下列範例會先設定連線至 Calendar Data API 的服務物件,然後將 HTTP POST 傳送至 ClientLogin 處理常式。

Java

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 G Suite account (as opposed to a Google/Gmail Account), you can streamline the login process by specifying the appropriate ClientLogin account type:

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);

.NET

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 G Suite account (as opposed to a Google/Gmail Account), you can streamline the login process by specifying the appropriate ClientLogin account type:

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

PHP

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 G Suite account (as opposed to a Google/Gmail Account), you can streamline the login process by specifying the appropriate ClientLogin account type:

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);

Python

如果您使用的是以 GDClient 為基礎的新版 2.0 以上版本類別,請使用:

import gdata.calendar.client

email = 'user@example.com'
password = 'pa$$word'
application_name = 'yourCompany-yourAppName-v1'

client = gdata.calendar.client.CalendarClient()
auth_token = client.ClientLogin(email, password,
                                application_name,
                                service='cl')

If you know your users will be using a G Suite account (as opposed to a Google/Gmail Account), you can streamline the login process by specifying the appropriate ClientLogin account type:

auth_token = client.ClientLogin(email, password,
                                application_name,
                                account_type='HOSTED',
                                service='cl')

Alternatively, if you're using the older v1.0 classes based off of GDataService, the calls are a bit different:

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()

與 v2.0 以上版本一樣,如果您的使用者將使用 G Suite 帳戶,您可以指定適當的 ClientLogin 帳戶類型:

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 an account-type parameter to HOSTED_OR_GOOGLE. That means ClientLogin will first try to authenticate the user's credentials as a G Suite 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 G Suite account. In that special case, set the account type to 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.

Recalling an auth token

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:

Java

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'

.NET

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'

PHP

$token = '12345abcde'; // TODO: Read user's token from your database
$client->getHttpClient()->setClientLoginToken($token);

$token = $client->getHttpClient()->getClientLoginToken(); // $token is '12345abcde'

Python

If you're using the newer v2.0+ classes based off of GDClient, use:

import gdata.gauth

token = '12345abcde'  # TODO: Read user's token from your database
client.auth_token = gdata.gauth.ClientLoginToken(token)

token = client.auth_token.token_string  # token is '12345abcde'

If you're using the older v1.0 classes based off of GDataService, the process is a bit different.

token = '12345abcde'  # TODO: Read user's token from your database
client.SetClientLoginToken(token)

token = client.GetClientLoginToken()  # token is '12345abcde'

Handling CAPTCHA challenges

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.

Java

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());
}

.NET

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);
}

PHP

$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();
  }
}

Python

如果您使用的是以 GDClient 為基礎的新版 2.0 以上版本類別,請使用:

import gdata.client

try:
  client.ClientLogin(email, password, application_name,
                     service='cl')
except gdata.client.CaptchaChallenge as challenge:
  print 'Please visit ' + challenge.captcha_url
  answer = raw_input('Answer to the challenge? ')
  client.ClientLogin(email, password, application_name,
                     captcha_token=challenge.captcha_token,
                     captcha_response=answer)
except gdata.client.BadAuthentication:
  exit('Users credentials were unrecognized')
except gdata.client.RequestError:
  exit('Login Error')

如果您使用的是以 GDataService 為基礎的舊版 v1.0 類別,程序會稍有不同。

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')

如要進一步瞭解人機驗證 (Captcha),請參閱「{0}為已安裝的應用程式進行驗證{/1}」文件的ClientLogin Response 部分

其他資源和樣本

返回頁首