אזהרה: המאמר הזה עוסק בממשקי API ישנים יותר של Google, ממשקי Google Data API. הוא רלוונטי רק לממשקי ה-API שמופיעים בספריית Google Data API, שרבים מהם הוחלפו בממשקי API חדשים יותר. מידע על API חדש ספציפי מופיע במסמכי התיעוד של ה-API החדש. למידע על הרשאת בקשות באמצעות API חדש יותר, אפשר לעיין במאמר אימות והרשאה של חשבונות Google.
במאמר הזה מוסבר איך להשתמש בספריות הלקוח של Google Data API כדי להתחבר אל אימות OAuth של Google לאפליקציות אינטרנט.
ממשק OAuth מאפשר לאפליקציה מבוססת-אינטרנט לגשת לשירות Google בשם משתמש. כדי לשמור על רמת אבטחה גבוהה, פרוטוקול OAuth מאפשר לאפליקציה לקבל אסימון גישה בלי לטפל בפרטי הכניסה לחשבון של המשתמש.
ספריות הלקוח של Google Data API מספקות שיטות שיעזרו לכם להשתמש ב-OAuth באפליקציית האינטרנט שלכם. באופן ספציפי, יש שיטות ליצירת טוקן בקשה, לאישור טוקן הבקשה ולהחלפת טוקן הבקשה המאושר בטוקן גישה. הספריות גם מטפלות באלגוריתמים הנדרשים לחתימה כשמבצעים בקשות לשירות נתונים של Google.
קהל
המסמך הזה מיועד למתכנתים שרוצים שאפליקציות מבוססות-אינטרנט שלהם יגשו לשירותי Google בשם המשתמשים, באמצעות ספריות הלקוח של Google Data APIs.
במסמך הזה אנחנו מניחים שאתם מכירים את ממשק OAuth ואת התהליך הכללי לשילוב OAuth באפליקציית האינטרנט שלכם. תיאור מלא של פרוטוקול OAuth זמין במאמר אימות OAuth לאפליקציות אינטרנט או במפרט הרשמי בכתובת oauth.net.
שימוש ב-OAuth עם 3 רגליים וב-Google Data APIs בלי ספריות הלקוח
אם אתם רוצים שאפליקציית האינטרנט שלכם תקיים אינטראקציה עם שירות נתונים של Google באמצעות OAuth כשיטת הרשאה, כל מה שאתם צריכים לדעת מופיע במאמר אימות OAuth לאפליקציות אינטרנט. אין צורך להשתמש בספריות הלקוח של Google Data APIs אם לא רוצים.
הנה תיאור של תהליך האימות של משתמש באפליקציה באמצעות OAuth:
- האפליקציה שולחת בקשה חתומה כדי לאחזר טוקן בקשת OAuth ראשוני מנקודת הקצה
OAuthRequestToken. - האפליקציה מפנה את המשתמש לכתובת ה-URL המתאימה של
OAuthAuthorizeTokenכדי לאשר את טוקן הבקשה. - אחרי מתן הגישה, המשתמש מופנה חזרה לאפליקציה (כתובת ה-URL
oauth_callback). - האפליקציה שולחת בקשה חתומה לשדרוג טוקן הבקשה המאושר לטוקן גישה באמצעות נקודת הקצה
OAuthGetAccessToken.
ספריות הלקוח של Google Data APIs מפשטות את תהליך ההרשאה הזה על ידי טיפול בפרטים שונים בשבילכם. במאמר הזה נסביר איך עושים את זה.
רישום אפליקציית האינטרנט
ב-OAuth, כל הקריאות ל-API צריכות להיות חתומות דיגיטלית. Google תומכת בשיטות החתימה HMAC-SHA1 ו-RSA-SHA1. כדי לחתום על בקשות, קודם צריך לרשום את האפליקציה ב-Google. אחרי ההרשמה, Google תספק לכם מפתח צרכן (וסוד לשימוש ב-HMAC-SHA1) ומקום להעלאת אישור ציבורי.
1. רישום הדומיין
צריך לפעול לפי השלבים שמפורטים במאמר בנושא הרשמה לאפליקציות מבוססות-אינטרנט.
2. יצירת זוג של מפתח פרטי / אישור ציבורי (אופציונלי)
אם בחרתם להשתמש ב-RSA-SHA1 כoauth_signature_method, תצטרכו ליצור זוג של RSAמפתח פרטי ואישור ציבורי עם חתימה עצמית. בקטע יצירת מפתח פרטי עם חתימה עצמית ואישור ציבורי (בהמשך) יש דוגמאות לאופן הפעולה.
עבודה עם OAuth בעל 3 רגליים וממשקי Google Data API: דוגמאות לספריות לקוח
בקטעים הבאים מוצגות דוגמאות לשימוש בשיטות של ספריית הלקוח של Google Data APIs כדי לבצע את השלבים שמפורטים בקטע עבודה עם OAuth במסמכי התיעוד של OAuth. כל הדוגמאות במסמך הזה מניחות שדומיין המארח של האפליקציה הוא example.com.
הגדרת ההיקף של הגישה לנתונים
כל שירות של Google מגדיר ערך scope שקובע את הגישה של טוקן לנתונים של המשתמש. ערכי ההיקף הזמינים מפורטים בשאלות הנפוצות בנושא נתונים של Google. לדוגמה, כדי להשתמש ב-Documents List API, צריך להגדיר את scope ל-https://docs.google.com/feeds/, כמו שמופיע בשאלות הנפוצות.
הערה: מגדירים את הערך scope לכתובת ה-URL הספציפית ביותר שמאפשרת את הגישה שאתם צריכים. כך מצמצמים את הסיכוי להשגת מידע אישי ולדליפתו בטעות. לדוגמה, אם רוצים לגשת לפיד של רשימת המסמכים הפרטיים של המשתמש הנוכחי, צריך להשתמש בהיקף https://docs.google.com/feeds/default/private/full במקום בהיקף רחב יותר כמו https://docs.google.com/feeds/, שמאפשר גישה לכל הפידים של רשימת המסמכים.
טוקנים עם כמה היקפי הרשאות
כדי ליצור אסימונים שמאפשרים גישה לכמה Google Data APIs, צריך להפריד בין כל היקף באמצעות רווח. בדוגמה שלמטה נוצר אסימון עם גישה לנתונים של משתמש ב-Google Docs וב-יומן Google.
scope=https://www.google.com/calendar/feeds/ https://docs.google.com/feeds/
קידוד כתובות URL
כדי להעביר תווים שאינם ASCII שמופיעים בכתובות URL, כולל נקודתיים, לוכסן ורווח, באמצעות HTTP, צריך לקודד אותם בפורמט URL. ספריות הלקוח של Google Data API מקודדות באופן אוטומטי פרמטרים של כתובות URL, כך שאתם יכולים פשוט להשתמש במחרוזות לא מקודדות של כתובות URL כשאתם מקצים ערכים לפרמטרים. לדוגמה, אפשר להגדיר את ההקצאה הבאה בקוד:
scope=https://www.google.com/calendar/feeds/ https://docs.google.com/feeds/
כשקוראים לספריית הלקוח, הפרמטר
scope מקודד אוטומטית לכתובת URL עם הערך הבא:
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 כשיטת החתימה:
אם אתם משתמשים במחלקות חדשות יותר מגרסה 2.0 ומעלה שמבוססות על GDClient, אתם צריכים להשתמש ב:
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)
לחלופין, אם אתם משתמשים במחלקות הישנות יותר מגרסה 1.0 שמבוססות על GDataService, הקריאות קצת שונות:
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.
אישור טוקן בקשה
כדי לאשר טוקן בקשה, האפליקציה צריכה להפנות את המשתמש לכתובת ה-URL של OAuthAuthorizeToken, שבה מוצגת לו בקשה להיכנס לחשבון Google שלו.
מידע נוסף על כתובת ה-URL של OAuthAuthorizeToken זמין במאמר המלא בנושא אימות OAuth לאפליקציות אינטרנט.
כדי ליצור את כתובת ה-URL OAuthAuthorizeToken באפליקציה, משתמשים בפרטים הבאים לכל ספריית לקוח. שימו לב שהדוגמאות האלה מבוססות על הדוגמאות הקודמות.
אחרי שיוצרים את כתובת ה-URL של דף האישור, האפליקציה יכולה להשתמש בה במגוון דרכים כדי לשלוח את המשתמש אל
ה-handler של 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>";
לחלופין, אפשר פשוט להפנות לכתובת ה-URL של האישור:
// If on a G Suite domain, use your domain for the hd param (e.g. 'example.com'). $consumer->redirect(array('hd' => 'default'));
Python
אם אתם משתמשים במחלקות חדשות יותר מגרסה 2.0 ומעלה שמבוססות על GDClient, אתם צריכים להשתמש ב:
# 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))
אם אתם משתמשים במחלקות ישנות יותר מגרסה 1.0 שמבוססות על GDataService, התהליך שונה קצת.
# 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);
שליפת הטוקן מכתובת ה-URL של הקריאה החוזרת
כש-Google מפנה בחזרה לאפליקציה שלכם, הפרמטר oauth_token מצורף לכתובת ה-URL oauth_callback_url כפרמטר של שאילתה.
לאחר מכן, האפליקציה צריכה לחלץ את ערך הטוקן מפרמטר השאילתה של כתובת ה-URL ולהגדיר מחדש את פרמטרי ה-OAuth.
ספריות הלקוח מספקות שיטות נוחות לחילוץ של oauth_token. הדוגמאות האלה מבוססות על הדוגמאות הקודמות.
Java
אם בחרתם לשמור את סוד הטוקן בכתובת ה-URL של הקריאה החוזרת (callback) (כשמשתמשים ב-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
אם אתם משתמשים במחלקות חדשות יותר מגרסה 2.0 ומעלה שמבוססות על GDClient, אתם צריכים להשתמש ב:
# 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)
אם אתם משתמשים במחלקות ישנות יותר מגרסה 1.0 שמבוססות על GDataService, השתמשו ב:
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
אם בחרתם לשמור את סוד הטוקן בכתובת ה-URL לקריאה חוזרת (callback):
OAuthUtil.UpdateOAuthParametersFromCallback(url, parameters);
שדרוג לאסימון גישה
השלב האחרון בתהליך קבלת טוקן OAuth הוא שדרוג של טוקן הבקשה המאושר לטוקן גישה לטווח ארוך באמצעות כתובת ה-URL 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
אם אתם משתמשים במחלקות חדשות יותר מגרסה 2.0 ומעלה שמבוססות על GDClient, אתם צריכים להשתמש ב:
# 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)
אם אתם משתמשים במחלקות ישנות יותר מגרסה 1.0 שמבוססות על GDataService, השתמשו ב:
access_token = client.UpgradeToOAuthAccessToken() # calls SetOAuthToken() for you
אם אתם משתמשים ב-gdata.gauth.AeSave() ב-App Engine, הטוקן והסוד של הטוקן יישמרו בשבילכם תחת המשתמש שמחובר כרגע.
.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 APIs כדי ליצור אינטראקציה עם השירות. הספרייה תדאג לחתום על הבקשות ולכלול את כותרת ההרשאה הנכונה בשבילכם. בדרך כלל, מאחזרים את האסימון של המשתמש מקובץ 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) ושאתם שולפים את המפתח או הסוד של האסימון הזה לשימוש מאוחר יותר.
אם אתם משתמשים במחלקות חדשות יותר מגרסה 2.0 ומעלה שמבוססות על GDClient, אתם צריכים להשתמש ב:
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
אם אתם משתמשים במחלקות ישנות יותר מגרסה 1.0 שמבוססות על GDataService, השתמשו ב:
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 תלת-רגלי
- דוגמאות ל-OAuth בבלוג בנושא טיפים ל-Google Data API
- מאמר: שימוש ב-OAuth עם Google Data APIs
- דוגמה לספריית לקוח Python
- ספריית לקוח Python דוגמה ל-Google App Engine
- דוגמה לספריית לקוח Java
- ספריית לקוח Java דוגמה ל-Google App Engine
- דוגמה לספריית לקוח Zend PHP
- מסמכי אימות OAuth לאפליקציות אינטרנט
- מסמכי תיעוד של OAuth.net
2 Legged OAuth
פרוטוקול OAuth עם שני רגליים מאפשר לאפליקציות מהימנות לגשת לנתוני Google של משתמשים בלי שהם מעורבים ישירות. שתי קבוצות עיקריות יכולות להשתמש ב-OAuth דו-רגלי:
אדמינים בדומיין G Suite: אדמינים יכולים ליצור סקריפטים ואפליקציות בהתאמה אישית שמנהלים את נתוני המשתמשים בדומיין שלהם באמצעות Google Data APIs. מידע על ניהול המפתח והסוד שמשויכים לדומיין G Suite שלכם ועל מתן בקרת גישה גלובלית זמין במאמר ניהול מפתח וסוד OAuth.
ספקי תוכנה של צד שלישי: ספקים עשויים להציע אפליקציות שמשתמשות ב-OAuth דו-רגלי כדי להשתלב עם G Suite. אפשר להעניק גישה לאפליקציות של צד שלישי בדף 'ניהול לקוח API' או באמצעות התקנה מ-G Suite Marketplace.
לא נדרש אסימון גישה לפי תהליך ההרשאה הרגיל (שנקרא גם OAuth עם 3 רגליים).
בדוגמאות הבאות של ספריות לקוח מוסבר איך להגדיר את הלקוח לשימוש ב-OAuth עם 2 רגליים באמצעות HMAC-SHA1.
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
אם אתם משתמשים במחלקות חדשות יותר מגרסה 2.0 ומעלה שמבוססות על GDClient, אתם צריכים להשתמש ב:
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
אם אתם משתמשים במחלקות ישנות יותר מגרסה 1.0 שמבוססות על GDataService, השתמשו ב:
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 דו-רגלי
- דוגמאות ל-OAuth עם שני רגליים בבלוג בנושא טיפים ל-Google Data API
- ספריית לקוח Java דוגמה ל-OAuth דו-רגלי
- ספריית לקוח Python TwoLeggedOAuthExample (למחלקות client.py) או 2_legged_oauth sample (למחלקות service.py)
- ספריית לקוח של .NET דוגמה ל-OAuth דו-רגלי
- מסמכי OAuth דו-רגלי
יצירת מפתח פרטי בחתימה עצמית ואישור ציבורי
המפתח הפרטי משמש ליצירת חתימה, שחייבת להיכלל בכל בקשה. Google משתמשת במפתח הציבורי שמוטמע באישור כדי לאמת את החתימה. המפתח הציבורי צריך להיות מפתח RSA של 1,024 ביט שמקודד באישור X.509 בפורמט PEM. צריך לשלוח את האישור ל-Google בזמן ההרשמה.
בקטעים הבאים מופיעות דוגמאות לאופן שבו אפשר ליצור מפתחות ואישורים באמצעות שני כלים ספציפיים: כלי השירות OpenSSL וכלי השירות keytool של Java.
הדוגמאות האלה לא ספציפיות ל-Google Data APIs, ואפשר להשתמש באותם כלי עזר כדי ליצור מפתחות לכל מטרה.
בדוגמאות מניחים ששם החברה הוא 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
Framework .NET לא מזהה מפתחות או אישורים שמאוחסנים בפורמט PEM. לכן, אחרי שיוצרים את קובץ ה-pem, צריך לבצע שלב נוסף:
openssl pkcs12 -export -in test_cert.pem -inkey myrsacert.pem -out myrsacert.pfx -name "Testing Certificate"
בשלב הזה נוצר קובץ PFX מהמפתח הפרטי ומהאישור שלכם. אפשר לייבא את הקובץ הזה לספריית הלקוח של .NET כדי לחתום דיגיטלית על בקשות שנשלחות אל Google Data APIs.
יצירת מפתחות ללקוח Java
לקוח Java מקבל מפתחות פרטיים בפורמט PKCS#8. אחרי שיוצרים מפתח או אישור באמצעות ההוראות שלמעלה, יוצרים קובץ .pk8 מקובץ ה- .pem שנוצר:
openssl pkcs8 -in myrsakey.pem -topk8 -nocrypt -out myrsakey.pk8
לחלופין, אפשר להשתמש ב-Java key store ובכלי 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 מציין את הסיסמה להגנה על מאגר המפתחות. הפרמטר -keypass מציין את הסיסמה להגנה על המפתח הפרטי.
כדי לכתוב את האישור לקובץ שאפשר להשתמש בו בכלי ManageDomains, משתמשים בפקודה הבאה:
# Output the public certificate to a file keytool -export -rfc -keystore ./Example.jks -storepass changeme \ -alias Example -file mycert.pem