警告:本頁面介紹的是 Google 舊版 API (Google Data API),僅適用於Google Data API 目錄中列出的 API,其中許多 API 已由新版 API 取代。如要瞭解特定新版 API,請參閱該 API 的說明文件。如要瞭解如何使用較新的 API 授權要求,請參閱「Google 帳戶驗證和授權」。
本文說明如何使用 Google Data API 用戶端程式庫,連線至 Google 的網路應用程式 OAuth 驗證。
OAuth 介面可讓網頁式應用程式代表使用者存取 Google 服務。為維持高安全等級,OAuth 可讓應用程式取得存取權杖,完全不必處理使用者的帳戶登入資訊。
Google Data API 用戶端程式庫提供的方法可協助您在網頁應用程式中使用 OAuth。具體來說,這些方法可用於建構及取得要求權杖、授權要求權杖,以及將授權要求權杖換成存取權杖。此外,程式庫也會在向 Google Data 服務提出要求時,處理必要的簽署演算法。
觀眾
本文適用於想讓網路應用程式代表使用者存取 Google 服務的程式設計人員,他們可以使用 Google Data API 用戶端程式庫。
本文假設您已熟悉 OAuth 介面,以及將 OAuth 併入網路應用程式的一般程序。如要完整瞭解 OAuth 通訊協定,請參閱「網路應用程式的 OAuth 驗證」或 oauth.net 的官方規格。
不使用用戶端程式庫,透過 3 向 OAuth 和 Google Data API 進行驗證
如果想讓網頁應用程式使用 OAuth 做為授權方法,與 Google 資料服務互動,請參閱「網頁應用程式的 OAuth 驗證」,瞭解所有相關資訊。如果您不想使用 Google Data API 用戶端程式庫,則無須使用。
以下是應用程式可能使用 OAuth 驗證使用者的流程大綱:
- 應用程式會發出已簽署的要求,從
OAuthRequestToken端點擷取初始 OAuth 要求權杖。 - 應用程式會將使用者重新導向至適當的
OAuthAuthorizeToken網址,以授權要求權杖。 - 授予存取權後,使用者會重新導向回您的應用程式 (
oauth_callback網址) - 您的應用程式會使用
OAuthGetAccessToken端點,傳送已簽署的要求,將授權要求權杖升級為存取權杖。
Google Data API 用戶端程式庫會為您處理各種詳細資料,簡化授權程序。本文將說明如何操作。
註冊網頁應用程式
OAuth 要求所有 API 呼叫都必須經過數位簽章。Google 支援 HMAC-SHA1 和 RSA-SHA1 簽章方法。如要簽署要求,應用程式必須先向 Google 註冊。註冊完成後,Google 會提供消費者金鑰 (以及搭配 HMAC-SHA1 使用的密碼),並提供上傳公開憑證的位置。
1. 註冊網域
請按照「註冊網頁應用程式」一文中的步驟操作。
2. 建立私密金鑰 / 公開憑證組 (選用)
如果選擇使用 RSA-SHA1 做為 oauth_signature_method,您需要建立自行簽署的RSA私密金鑰和公開憑證組。如需相關範例,請參閱下方的「產生自簽私密金鑰和公開憑證」。
使用 3 向 OAuth 和 Google Data API:用戶端程式庫範例
以下各節提供範例,說明如何使用 Google Data API 用戶端程式庫方法,按照 OAuth 文件「使用 OAuth」一節所述步驟操作。本文中的所有範例都假設應用程式主機網域為 example.com。
判斷資料存取範圍
每項 Google 服務都會定義 scope 值,決定權杖可存取的使用者資料。如需可用的範圍值,請參閱 Google 數據常見問題。舉例來說,如要使用 Documents List API,請將 scope 設為 https://docs.google.com/feeds/,如常見問題所述。
注意:請將 scope 值設為允許所需存取權的最窄網址。這麼做可降低不慎取得及洩漏個人資料的風險。舉例來說,如要存取目前使用者的私人文件清單動態饋給,請使用 https://docs.google.com/feeds/default/private/full 範圍,而非 https://docs.google.com/feeds/ 等較廣泛的範圍,因為後者會提供所有文件清單動態饋給的存取權。
多範圍權杖
如要建立可存取多個 Google Data API 的權杖,請以空格字元分隔每個範圍。以下範例會建立權杖,可存取使用者的 Google 文件和 Google 日曆資料。
scope=https://www.google.com/calendar/feeds/ https://docs.google.com/feeds/
網址編碼
網址中出現的非 ASCII 字元 (包括半形冒號、斜線和空格),必須經過網址編碼,才能透過 HTTP 傳輸。Google Data API 用戶端程式庫會自動為您進行網址編碼參數,因此您只需在為參數指派值時使用非網址編碼字串即可。舉例來說,您可以在程式碼中進行下列指派作業:
scope=https://www.google.com/calendar/feeds/ https://docs.google.com/feeds/
呼叫用戶端程式庫時,系統會自動將
scope 參數網址編碼為下列值:
https%3a%2f%2fwww.google.com%2fcalendar%2ffeeds%2f+https%3a%2f%2fdocs.google.com%2ffeeds%2f
擷取要求權杖
Java
對於 HMAC-SHA1,您需要某種方式來保存權杖密鑰 (在回應中取得),以便建立從核准頁面返回的 OAuth 權杖物件。如要這麼做,請設定工作階段變數或 Cookie。
import com.google.gdata.client.docs.*; import com.google.gdata.client.authn.oauth.*; String CONSUMER_KEY = "example.com"; String CONSUMER_SECRET = "abc123doremi"; GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); oauthParameters.setOAuthConsumerKey(CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET); oauthParameters.setScope("https://docs.google.com/feeds/"); oauthParameters.setOAuthCallback("http://www.example.com/UpgradeToken.jsp"); GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthHmacSha1Signer()); oauthHelper.getUnauthorizedRequestToken(oauthParameters);
使用 RSA-SHA1 時,oauth_token_secret 不會用到,因此不需要保存權杖密鑰。
import com.google.gdata.client.docs.*; import com.google.gdata.client.authn.oauth.*; String CONSUMER_KEY = "example.com"; GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); oauthParameters.setOAuthConsumerKey(CONSUMER_KEY); oauthParameters.setScope("https://docs.google.com/feeds/"); oauthParameters.setOAuthCallback("http://www.example.com/UpgradeToken.jsp"); PrivateKey privKey = getPrivateKey("/path/to/your/rsakey.pk8"); GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthRsaSha1Signer(privKey)); oauthHelper.getUnauthorizedRequestToken(oauthParameters); ... public static PrivateKey getPrivateKey(String privKeyFileName) { File privKeyFile = new File(privKeyFileName); FileInputStream fis = new FileInputStream(privKeyFile); DataInputStream dis = new DataInputStream(fis); byte[] privKeyBytes = new byte[(int) privKeyFile.length()]; dis.read(privKeyBytes); dis.close(); fis.close(); String BEGIN = "-----BEGIN PRIVATE KEY-----"; String END = "-----END PRIVATE KEY-----"; String str = new String(privKeyBytes); if (str.contains(BEGIN) && str.contains(END)) { str = str.substring(BEGIN.length(), str.lastIndexOf(END)); } KeyFactory fac = KeyFactory.getInstance("RSA"); EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(Base64.decode(str)); return fac.generatePrivate(privKeySpec); }
PHP
使用 HMAC-SHA1 做為簽章方法:
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)))); }
使用 RSA-SHA1 做為簽章方法:
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
使用 HMAC-SHA1 做為簽章方法:
如果您使用的是以 GDClient 為基礎的較新 v2.0 以上類別,請使用:
import gdata.gauth import gdata.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')
使用 RSA-SHA1 做為簽章方法:
... 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)
或者,如果您使用以 GDataService 為基礎的舊版 1.0 類別,呼叫方式會略有不同:
import gdata.auth import gdata.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)
使用 RSA-SHA1 做為簽章方法:
... 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
使用 HMAC-SHA1 做為簽章方法:
using Google.GData.Client; string CONSUMER_KEY = "example.com"; string CONSUMER_SECRET = "abc123doremi"; // Multi-scoped token. string SCOPE = "https://www.google.com/calendar/feeds/ https://www.google.com/m8/feeds/"; OAuthParameters parameters = new OAuthParameters() { ConsumerKey = CONSUMER_KEY, ConsumerSecret = CONSUMER_SECRET, Scope = SCOPE, Callback = "http://myapp.example.com/access_token", SignatureMethod = "HMAC-SHA1" } OAuthUtil.GetUnauthorizedRequestToken(parameters);
使用 RSA-SHA1 做為簽章方法:
RSA-SHA1 is not supported yet.
授權要求權杖
如要授權要求權杖,應用程式必須將使用者重新導向 OAuthAuthorizeToken 網址,提示他們登入 Google 帳戶。
如要進一步瞭解 OAuthAuthorizeToken 網址,請參閱完整的「網頁應用程式的 OAuth 驗證」。
如要在應用程式中建構 OAuthAuthorizeToken 網址,請為每個用戶端程式庫使用下列項目。請注意,這些範例是以先前的範例為基礎。
建構核准頁面網址後,應用程式就能以各種方式使用該網址,將使用者傳送至 OAuthAuthorizeToken 處理常式。最常見的做法是重新導向使用者,或顯示該網頁的連結。
Java
針對 HMAC-SHA1:
String approvalPageUrl = oauthHelper.createUserAuthorizationUrl(oauthParameters); System.out.println(approvalPageUrl);
針對 RSA-SHA1:
String approvalPageUrl = 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>";
或者,您也可以直接重新導向至核准網址:
// If on a G Suite domain, use your domain for the hd param (e.g. 'example.com'). $consumer->redirect(array('hd' => 'default'));
Python
如果您使用的是以 GDClient 為基礎的較新 v2.0 以上類別,請使用:
# 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))
如果您使用的是以 GDataService 為基礎的舊版 1.0 類別,程序會略有不同。
# 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);
從回呼網址擷取權杖
Google 重新導向回應用程式時,oauth_token 會以查詢參數的形式附加至「oauth_callback_url」網址。然後,應用程式應從網址查詢參數中擷取權杖值,並重新建立 OAuth 參數。
用戶端程式庫提供便利的方法,可擷取 oauth_token。這些範例是以先前的範例為基礎。
Java
如果您選擇在回呼網址中保留權杖密鑰 (使用 HMAC-SHA1 時):
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); oauthParameters.setOAuthConsumerKey(CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET); GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthHmacSha1Signer()); oauthHelper.getOAuthParametersFromCallback(request.getQueryString(), oauthParameters);
與 RSA-SHA1 的唯一差異是簽署方法:
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); oauthParameters.setOAuthConsumerKey(CONSUMER_KEY); PrivateKey privKey = getPrivateKey("/path/to/your/rsakey.pk8"); GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthRsaSha1Signer(privKey)); oauthHelper.getOAuthParametersFromCallback(request.getQueryString(), oauthParameters);
PHP
使用 PHP 程式庫時,不必執行這個步驟。
Python
如果您使用的是以 GDClient 為基礎的較新 v2.0 以上類別,請使用:
# 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)
如果您使用的是以 GDataService 為基礎的舊版 v1.0 類別,請使用:
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'
RSA-SHA1 的程序類似,但不含權杖密鑰:
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
如果您選擇在回呼網址中保留權杖密鑰:
OAuthUtil.UpdateOAuthParametersFromCallback(url, parameters);
升級為存取權杖
OAuth 權杖流程的最後一個步驟,是使用 OAuthGetAccessToken 網址將授權要求權杖升級為長期存取權杖,詳情請參閱完整的「網路應用程式的 OAuth 驗證」文件。
以下是使用各個用戶端程式庫的範例:
Java
String accessToken = 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); String accessTokenSecret = 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
如果您使用的是以 GDClient 為基礎的較新 v2.0 以上類別,請使用:
# 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)
如果您使用的是以 GDataService 為基礎的舊版 v1.0 類別,請使用:
access_token = client.UpgradeToOAuthAccessToken() # calls SetOAuthToken() for you
如果您在 App Engine 上使用 gdata.gauth.AeSave(),系統會為您儲存目前登入使用者的權杖和權杖密鑰。
.NET
OAuthUtil.GetAccessToken(parameters); // If you want to extract the OAuth Token/TokenSecret from the OAuthParameters instance: string accessToken = parameter.Token; Console.WriteLine("OAuth Access Token: " + accessToken); string accessTokenSecret = parameter.TokenSecret; Console.WriteLine("OAuth Access Token's Secret: " + accessTokenSecret);
注意:如果您使用 HMAC-SHA1,請務必將存取權杖的權杖密碼與權杖值一併儲存在資料庫中,否則您將無法正確重建 OAuth 參數以供日後使用。
使用存取憑證
取得存取權杖後,請使用標準的 Google Data API 用戶端程式庫呼叫與服務互動。程式庫會負責簽署要求,並為您加入正確的授權標頭。通常您會從 Cookie 或資料庫中擷取使用者的權杖。這些範例說明如何重建 OAuth 參數,並發出用戶端程式庫呼叫。
Java
如果您是使用 HMAC-SHA1:
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); oauthParameters.setOAuthConsumerKey(CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET); oauthParameters.setOAuthToken(ACCESS_TOKEN); oauthParameters.setOAuthTokenSecret(TOKEN_SECRET); DocsService client = new DocsService("yourCompany-YourAppName-v1"); client.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer()); URL feedUrl = new URL("https://docs.google.com/feeds/default/private/full"); DocumentListFeed resultFeed = client.getFeed(feedUrl, DocumentListFeed.class); for (DocumentListEntry entry : resultFeed.getEntries()) { System.out.println(entry.getTitle().getPlainText()); }
與 RSA-SHA1 的不同之處在於,您不需要設定存取權杖的密碼,且建構簽署者物件的方式也不同:
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); oauthParameters.setOAuthConsumerKey(CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET); oauthParameters.setOAuthToken(ACCESS_TOKEN); PrivateKey privKey = getPrivateKey("/path/to/your/rsakey.pk8"); // See above for the defintion of getPrivateKey() DocsService client = new DocsService("yourCompany-YourAppName-v1"); client.setOAuthCredentials(oauthParameters, new OAuthRsaSha1Signer(privKey)); URL feedUrl = new URL("https://docs.google.com/feeds/default/private/full"); DocumentListFeed resultFeed = client.getFeed(feedUrl, DocumentListFeed.class); for (DocumentListEntry entry : 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
這個程式碼片段假設您已擷取存取權杖 (使用 HMAC-SHA1),並回呼該權杖金鑰/密鑰以供日後使用。
如果您使用的是以 GDClient 為基礎的較新 v2.0 以上類別,請使用:
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
如果您使用的是以 GDataService 為基礎的舊版 v1.0 類別,請使用:
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
如果您是使用 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);
}與 RSA-SHA1 的不同之處在於,您不需要設定存取權杖的密碼,且建構簽署者物件的方式也不同:
RSA-SHA1 is not supported yet.
其他三足式 OAuth 資源和範例
- Google Data API 提示網誌上的 OAuth 範例
- 文章:使用 OAuth 搭配 Google Data API
- Python 用戶端程式庫範例
- Python 用戶端程式庫 Google App Engine 範例
- Java 用戶端程式庫範例
- Java 用戶端程式庫 Google App Engine 範例
- Zend PHP 用戶端程式庫範例
- 網頁應用程式的 OAuth 驗證說明文件
- OAuth.net 說明文件
雙足式 OAuth
2 legged OAuth 可讓受信任的應用程式存取使用者的 Google 資料,不必經過使用者直接參與。有兩大群組可使用雙足式 OAuth:
G Suite 網域管理員:管理員可以透過 Google Data API 建立指令碼和自訂應用程式,管理網域的使用者資料。如要瞭解如何管理與 G Suite 網域相關聯的金鑰和密鑰,以及如何授予全域存取權控管權限,請參閱「管理 OAuth 金鑰和密鑰」。
第三方軟體供應商:供應商可能會提供使用雙向 OAuth 的應用程式,以便與 G Suite 整合。您可以在「管理 API 用戶端」頁面授予第三方應用程式存取權,也可以從 G Suite Marketplace 安裝應用程式。
根據一般授權流程 (也稱為三足式 OAuth),不需要存取權杖。
下列用戶端程式庫範例示範如何設定用戶端,透過 HMAC-SHA1 使用雙向 OAuth。
Java
import com.google.gdata.client.docs.*; import com.google.gdata.client.authn.oauth.*; String CONSUMER_KEY = "example.com"; String CONSUMER_SECRET = "abc123doremi"; GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); oauthParameters.setOAuthConsumerKey(CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET); DocsService client = new DocsService("yourCompany-YourAppName-v1"); client.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer()); // Retrieve user's list of Google Docs String user = "any.user@anydomain.com"; URL feedUrl = new URL("https://docs.google.com/feeds/default/private/full" + "?xoauth_requestor_id=" + user); DocumentListFeed resultFeed = client.getFeed(feedUrl, DocumentListFeed.class); for (DocumentListEntry entry : 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
如果您使用的是以 GDClient 為基礎的較新 v2.0 以上類別,請使用:
import gdata.gauth import gdata.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
如果您使用的是以 GDataService 為基礎的舊版 v1.0 類別,請使用:
import gdata.auth import gdata.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
using Google.GData.Client; using Google.GData.Documents; // Create an OAuth factory to use GOAuthRequestFactory requestFactory = new GOAuthRequestFactory("writely", "yourCompany-YourAppName-v1"); requestFactory.ConsumerKey = "example.com"; requestFactory.ConsumerSecret = "abc123doremi"; String user = "any.user@anydomain.com"; DocumentsService client = new DocumentsService("yourCompany-YourAppName-v1"); client.RequestFactory = requestFactory; // Retrieve user's list of Google Docs DocumentsListQuery query = new DocumentsListQuery(); query.Uri = new OAuthUri("https://docs.google.com/feeds/default/private/full", user, requestFactory.ConsumerKey); DocumentsFeed feed = client.Query(query); foreach (DocumentEntry entry in feed.Entries) { Console.WriteLine(entry.Title.Text); }
其他雙足式 OAuth 資源和範例
- Google Data API Tips Blog 上的雙足式 OAuth 範例
- Java 用戶端程式庫 2-Legged OAuth 範例
- Python 用戶端程式庫 TwoLeggedOAuthExample (適用於 client.py 類別) 或 2_legged_oauth 範例 (適用於 service.py 類別)
- .NET 用戶端程式庫 2-Legged OAuth 範例
- 雙足式 OAuth 文件
產生自行簽署的私密金鑰和公開憑證
私密金鑰用於產生簽章,且必須隨附於每項要求。Google 會使用憑證內嵌的公開金鑰驗證簽名。公開金鑰必須是 1024 位元的 RSA 金鑰,並以 PEM 格式編碼為 X.509 憑證。註冊時,請將認證傳送給 Google。
以下各節提供範例,說明如何使用兩種特定工具 (OpenSSL 公用程式和 Java 的 keytool 公用程式) 產生金鑰和憑證。
這些範例並非 Google Data API 專用,您可以使用相同的公用程式產生任何用途的金鑰。
以下範例假設貴公司名稱為 My_Company,位於美國加州山景城,網域名稱為 example.com。
使用 OpenSSL 產生金鑰
如要建立一組 RSA 金鑰和對應的憑證,可以使用下列指令:
# 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
警告:加入 -nodes 參數會建立私密金鑰,但不會設定密碼來保護金鑰。不過,為提高安全性,建議您省略這個參數。
-sha1 參數指定金鑰將用於產生 SHA1 簽章。
-subj 參數會指定憑證代表的應用程式身分。
-keyout 參數會指定包含金鑰的檔案。這個檔案包含機密資訊,請妥善保護,不要與任何人分享。
-out 參數會指定包含 PEM 格式憑證的檔案 (註冊時可傳送給 Google)。
為 .NET 用戶端產生金鑰
.NET 架構無法解讀以 PEM 格式儲存的金鑰或憑證。因此,建立 .pem 檔案後,還需要執行下列步驟:
openssl pkcs12 -export -in test_cert.pem -inkey myrsacert.pem -out myrsacert.pfx -name "Testing Certificate"
這個步驟會從私密金鑰和憑證產生 PFX 檔案。這個檔案可以匯入 .NET 用戶端程式庫,用於以數位方式簽署對 Google Data API 提出的要求。
為 Java 用戶端產生金鑰
Java 用戶端接受 PKCS#8 格式的私密金鑰。使用上述指示產生金鑰/憑證後,請從產生的 .pem 檔案建立 .pk8 檔案:
openssl pkcs8 -in myrsakey.pem -topk8 -nocrypt -out myrsakey.pk8
或者,您也可以使用 Java 金鑰儲存區和 keytool 公用程式,建立一對 RSA 金鑰和對應的憑證。使用下列指令:
# Generate the RSA keys and certificate keytool -genkey -v -alias Example -keystore ./Example.jks\ -keyalg RSA -sigalg SHA1withRSA\ -dname "CN=www.example.com, OU=Engineering, O=My_Company, L=Mountain View, ST=CA, C=US"\ -storepass changeme -keypass changeme
警告:「changeme」並非理想密碼,這只是範例。
-dname 參數會指定憑證代表的應用程式身分。-storepass 參數會指定保護 KeyStore 的密碼。-keypass 參數會指定密碼來保護私密金鑰。
如要將憑證寫入可在 ManageDomains 工具中使用的檔案,請使用下列指令:
# Output the public certificate to a file keytool -export -rfc -keystore ./Example.jks -storepass changeme \ -alias Example -file mycert.pem