שימוש ב-AuthSub ב-ActionScript

במאמר הזה מוסבר איך להשתמש במערכת האימות AuthSub של Google מאפליקציית Flash או Silverlight.

הערה: אם אתם כבר מכירים את AuthSub, שירות אימות החשבון של Google לאפליקציות מבוססות-אינטרנט, תראו ש-AuthSub ל-ActionScript דומה מאוד מבחינה קונספטואלית. ההטמעה הבסיסית שונה, אבל ההבדלים לא חשובים לכם כמפתחים של אפליקציות לקוח. בחלק מהתיעוד, בהקשרים שבהם ההבחנה לא רלוונטית, אנחנו מתייחסים ל-AuthSub ל-ActionScript כאל "AuthSub" בקיצור.

ממשק AuthSub for ActionScript מאפשר לאפליקציות Flash או Silverlight לבצע אימות להזנות מוגנות של Google Data API בשם משתמש. כדי לשמור על רמת אבטחה גבוהה, הממשק מאפשר לאפליקציה לקבל אסימון אימות בלי לטפל בפרטי הכניסה של המשתמש לחשבון.

‫AuthSub for ActionScript הוא וריאציה של AuthSub for JavaScript. בדומה ל-AuthSub ל-JavaScript, הוא מספק שיטה חוצת-דומיינים לאימות של אפליקציות לקוח מדף אינטרנט שמתארח בדומיין שאינו של Google. הוא שונה מ-AuthSub הרגיל בכך ששירות האימות נמצא בדומיין אחר (accounts.googleapis.com במקום www.google.com) ומספק קובץ crossdomain.xml שמאפשר גישה לדומיין הזה מאתרים חיצוניים.

אפשר גם להצטרף לקבוצת Google Accounts API כדי להשתתף בדיונים על השימוש בכל ממשקי ה-API של שירות האימות.

קהל

המאמר הזה מיועד למתכנתים שמפתחים אפליקציות אינטרנט ב-Flash או ב-Silverlight שנותנות גישה לשירותי Google.

הנחת המוצא במסמך הזה היא שאתם מבינים את הרעיונות הכלליים שמאחורי הפרוטוקול של Google Data APIs וממשק AuthSub. בנוסף, אנחנו יוצאים מנקודת הנחה שאתם יודעים לתכנת ב-ActionScript.

סביבות נתמכות

‫AuthSub ל-ActionScript נתמך כרגע ב-Firefox מגרסה 1.5 ואילך וב-Internet Explorer מגרסה 6.0 ואילך, עם Flash מגרסה 9.0 ואילך או Silverlight מגרסה 2.0 ואילך.

איך פועל AuthSub ב-ActionScript

הנה סיכום קצר של אופן התקשורת בין אפליקציית אינטרנט, שירות האימות של Google ושירות נתונים של Google:

  1. כדי לגשת לשירות נתונים של Google בשם משתמש, לאפליקציית האינטרנט צריך להיות אסימון אימות תקף. בדרך כלל, האסימון הזה מאוחסן בקובץ Cookie באפליקציות. אם קובץ Cookie כזה לא קיים, אפליקציית האינטרנט צריכה לקבל את האסימון באמצעות AuthSub. כדי לקבל אסימון, אפליקציית האינטרנט מבצעת קריאה להתחברות AuthSub for ActionScript לשירות האימות, ומציינת את השירות שאליו רוצים לגשת.
  2. כשמתקבלת בקשה מאפליקציית האינטרנט, שירות האימות מפנה את המשתמש לדף 'בקשת גישה'. בדף הזה המשתמש מתבקש להיכנס לחשבון Google שלו ולאשר או לדחות את הגישה לשירות Google.
  3. המשתמש מחליט אם לאשר או לדחות את הגישה לאפליקציית האינטרנט. אם המשתמש דוחה את הגישה, הוא מופנה לדף של Google ולא חזרה לאפליקציית האינטרנט.
  4. אם המשתמש מתחבר בהצלחה ומעניק גישה, שירות האימות מפנה את המשתמש בחזרה לכתובת ה-URL של אפליקציית האינטרנט שביצעה את הקריאה המקורית. ההפניה האוטומטית מעבירה טוקן אימות לשירות שצוין באמצעות פרמטר של שאילתה. האפליקציה צריכה לאחסן את הטוקן כקובץ Cookie בדפדפן של המשתמש, בדומיין של אפליקציית האינטרנט. הטוקן תקף עד שהוא מבוטל. (המלצות לגבי ביטול אסימונים מפורטות בקטע מידע על אסימונים).
  5. אפליקציית האינטרנט יוצרת קשר עם שירות הנתונים של Google ושולחת את אסימון האימות עם כל בקשה שנשלחת לשירות.
  6. אם שירות הנתונים של Google מזהה את האסימון, הוא מספק את הנתונים המבוקשים.

שימוש ב-AuthSub לממשק ActionScript

‫AuthSub ל-ActionScript, או AuthSubAS, מספק נקודת קצה של AuthSub בין דומיינים לאפליקציות Flash (או Silverlight) שמשתמשות ב-Google Data APIs.

‫AuthSubAS מספק שיקוף של נקודות הקצה של AuthSub שנמצאות ב-google.com, עם קובץ crossdomain.xml נוסף שמאפשר ל-Flash (או ל-Silverlight) לגשת לנקודות הקצה האלה. לדוגמה, אפשר לגשת לנקודת הקצה AuthSubSessionToken דרך https://accounts.googleapis.com/accounts/AuthSubSessionToken.

בשלבים הבאים מוסבר איך לקבל אסימון אימות ולהשתמש בו כדי לגשת לשירות Google מאפליקציית Flash.

  1. הגדרת מדיניות בכמה דומיינים

    כדי להשתמש ב-Flash בצורה חוצת-דומיינים, צריך לאתחל אותו עם מדיניות לכל דומיין חיצוני שאליו רוצים לגשת. כדי לעשות זאת, מפעילים את ה-method‏ Security.loadPolicyFile(policy) של ActionScript לכל דומיין, באופן הבא:

    <?xml version="1.0" encoding="utf-8"?>
    <Application xmlns="http://www.adobe.com/2006/mxml"
      initialize="onInitialized()"
      applicationComplete="onLoaded()">
      <Script>
        import flash.external.ExternalInterface;
        import flash.net.navigateToURL;
        import mx.controls.Alert;
    
        private function onInitialized() : void {
          // Load the cross domain policy file for each of the googleapis.com
          // domains used. At the very least, we need the ones for the API (photos,
          // in this case) and the one for AuthSub for ActionScript (accounts).
          Security.loadPolicyFile('http://photos.googleapis.com/data/crossdomain.xml');
          Security.loadPolicyFile('https://accounts.googleapis.com/crossdomain.xml');
        }

    הצגת הדוגמה המלאה

    שימו לב שבמקרה הזה אנחנו טוענים את המדיניות עבור accounts.googleapis.com (AuthSubAS) ועבור photos.googleapis.com/data (PicasaWeb, שאליה ניגשים בהמשך הדוגמה).

  2. שולחים בקשה לטוקן לשימוש חד-פעמי.

    השלב הראשון בתהליך AuthSub הוא לבקש אסימון לשימוש חד-פעמי מנקודת הקצה של AuthSub. האפליקציה צריכה לעשות זאת על ידי הפעלת קריאה לנקודת הקצה AuthSubRequest, באופן הבא:

          var getTokenPage : URLRequest = new URLRequest('https://www.google.com/accounts/AuthSubRequest');
    
          // Construct the parameters of the AuthSub request. These are the same parameters
          // as normal AuthSub, which can be found here: /accounts/docs/AuthSub.html#AuthSubRequest
          var authSubParams : URLVariables = new URLVariables();
          authSubParams['scope'] = 'http://photos.googleapis.com/data'; // photos API
          authSubParams['session'] = 1; // single-use token
          authSubParams['secure'] = 0; // non-secure apps
          authSubParams['next'] = 'photos.swf'; // The URL of this app.
    
          getTokenPage.data =  authSubParams;
          navigateToURL(getTokenPage, '_top');

    הצגת הדוגמה המלאה

    השיטה הזו דורשת ערך היקף. כל שירות של Google מגדיר את היקף הגישה שהוא מאפשר, ואתם צריכים להפנות להיקף הזה בבקשה לטוקן. כדי לקבוע באיזה ערך של היקף הרשאות להשתמש, כדאי לעיין במסמכי העזרה של שירות Google שאליו רוצים לגשת. ההיקף נראה כמו כתובת URL. יכול להיות שזו כתובת URL פשוטה שמזהה את השירות, או שהוא יכול לציין גישה מוגבלת יותר, כמו הגבלת הגישה לקריאה בלבד. אם השירות מציע בחירה של היקפי הרשאות, כדאי לבקש את האסימון עם היקף ההרשאות הכי מצומצם שאפשר. לדוגמה, כדי לגשת לפידים של נתונים ביומן Google, צריך להשתמש בהיקף 'http://www.google.com/calendar/feeds' ולא בהיקף 'http://www.google.com/calendar'.

    טיפים:

    • מומלץ מאוד לספק כפתור התחברות או מנגנון אחר לקלט משתמש כדי להנחות את המשתמש להתחיל את תהליך ההתחברות באופן ידני. אם במקום זאת תבדקו ותפנו אוטומטית מיד אחרי הטעינה, בלי לחכות לאינטראקציה של המשתמש, הדבר הראשון שהמשתמש יראה כשהוא יגיע לדף שלכם הוא דף כניסה לחשבון Google. אם המשתמש מחליט לא להיכנס לחשבון, Google לא מפנה אותו בחזרה לדף שלכם. לכן, מנקודת המבט של המשתמש, הוא ניסה להיכנס לדף שלכם אבל נשלח למקום אחר ולא הוחזר אליו. התרחיש הזה עלול לבלבל את המשתמשים ולתסכל אותם.
    • אפליקציות שצריכות לגשת ליותר משירות Google אחד עבור משתמש מסוים צריכות לבקש טוקן חדש לכל שירות חדש (כי לכל שירות יש היקף שונה).

  3. שליחת בקשה לטוקן אימות.

    נקודת הקצה AuthSubRequest תחזיר לאפליקציה שלכם אסימון לשימוש חד-פעמי על ידי הגדרת כתובת ה-URL של הדפדפן של המשתמש ל-http://yourWebAppUrl?token=singleUseToken. אחרי שהאפליקציה מקבלת את האסימון לשימוש חד-פעמי, היא צריכה להחליף אותו באסימון לשימוש רב-פעמי (לטווח ארוך), שאפשר להשתמש בו כדי לשלוח בקשות לפידים של נתונים ב-Google. כדי לעשות זאת, מבצעים קריאה ל-method‏ AuthSubSessionToken עם טוקן לשימוש חד-פעמי.

    האפליקציה צריכה לבדוק אם הפרמטר token מופיע בכתובת ה-URL כשהיא נטענת:

        private function onLoaded() : void {
    
          // Once the application has loaded, check to see if an AuthSub token was
    // placed into the current page's URL. If it was, the user has already
    // authenticated, and we can continue to connect to the the service itself.
    var searchPortion : String = ExternalInterface.call('window.location.search.toString'); if (searchPortion.length > 0) { // remove the ? from the token and extract the token. searchPortion = searchPortion.substring(1); // NOTE: Real applications should parse the URL properly. if (searchPortion.indexOf('token=') == 0) { getLongLivedToken(searchPortion.substring(6)); return; } // more code ... }

    הצגת הדוגמה המלאה

    אם האסימון נמצא, צריך לקרוא לשיטה כמו getLongLivedToken, שמפעילה את נקודת הקצה AuthSubSessionToken:

        private function getLongLivedToken(singleUseToken : String) : void {
          // Construct a call to the AuthSub for ActionScript endpoint on accounts.googleapis.com.
          // This call will exchange the single use token given to use by AuthSub for a long-term
          // token that we can use to make requests to endpoints such as Photos.
          var getTokenRequest : URLRequest = new URLRequest('https://accounts.googleapis.com/accounts/AuthSubSessionToken');
    
          // Due to a bug in Flash, a URLRequest with a GET request will
          // not properly send headers. We therefore use POST for this and *ALL*
          // requests.
          getTokenRequest.method = URLRequestMethod.POST;
    
          // Due to a bug in Flash, a URLRequest without a valid parameter will
          // not properly send headers. We therefore add a useless parameter to
          // make this code work.
          getTokenRequest.data = new URLVariables('pleaseignore=ignore');
    
          // Add the AuthSub for ActionScript headers.
          getTokenRequest.requestHeaders.push(new URLRequestHeader('Authorization', 'AuthSub token="' + singleUseToken + '"'));
    
          // Create the loader to get the token itself. The loader will callback
          // to the following event handlers if and when the server responds.
          var getToken : URLLoader = new URLLoader();
          getToken.addEventListener(Event.COMPLETE, onGetTokenResult);
          getToken.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onGetTokenFailed);
          getToken.addEventListener(IOErrorEvent.IO_ERROR, onGetTokenFailed);
    
          try {
            getToken.load(getTokenRequest);
          } catch (e : Error) {
            Alert.show('Some error occurred: ' + e);
          }

    הצגת הדוגמה המלאה

    שיטה כמו onGetTokenResult handler צריכה לשמור את האסימון שמוחזר:

        private function onGetTokenResult(e : Event) : void {
          // Load the parameters from the response.
          var getToken : URLLoader = URLLoader(e.target);
          var params : URLVariables = new URLVariables(getToken.data);
    
          // Parse the session token from the result. Real applications
          // might at this point store the token in a long-term cookie so
          // that repeated usages of the application do not require this entire
          // authentication process.
          sessionToken = params.Token;
    
          // Trim the newline from the end of the session token.
          sessionToken = sessionToken.substring(0, sessionToken.length - 1);
       }

    הצגת הדוגמה המלאה

    טיפים:

    • מומלץ מאוד שהאפליקציה שלכם תאחסן את הטוקן לטווח ארוך בקובץ Cookie, ותבדוק אותו לפני הבדיקה של הטוקן לטווח קצר. כך המשתמשים לא יצטרכו להיכנס לדף האישור של AuthSub בכל פעם שהם רוצים להשתמש באפליקציה שלכם.

  4. שימוש בטוקן אימות

    כדי להשתמש באסימון האימות, צריך לצרף אותו באמצעות כותרת Authorization לכל בקשה שנשלחת לשירות Google:

    Authorization: AuthSub token="(session token goes here)"

    דוגמה ב-ActionScript לשירות Photos:

          // Prepare a request to the photos API for the private album
          // of the user.
          var albumRequest : URLRequest = new URLRequest('http://photos.googleapis.com/data/feed/api/user/default');
          albumRequest.data = new URLVariables('access=private&v=2&err=xml');
    
          // Due to a bug in Flash, a URLRequest with a GET request will
          // not properly send headers. We therefore use POST for this and *ALL*
          // requests.
          albumRequest.method = URLRequestMethod.POST;
    
          var authsubHeader : String = 'AuthSub token="' + sessionToken + '"';
    
          // Add the Authorization header which uses the session token.
          albumRequest.requestHeaders.push(new URLRequestHeader('Authorization', authsubHeader));
    
          // The X-HTTP-Method-Override header tells the Photos API to treat this request
          // as a GET request, even though it is being conducted as a POST (due to the bug
          // mentioned above). This is very important, as GData APIs will react differently
          // to different HTTP request types.
          albumRequest.requestHeaders.push(new URLRequestHeader('X-HTTP-Method-Override', 'GET'));
    
          // We expect ATOM XML to be returned.
          albumRequest.requestHeaders.push(new URLRequestHeader('Content-Type', 'application/atom+xml'));

    הצגת הדוגמה המלאה

  5. ‫Google ממליצה לספק תכונה של יציאה ידנית מהחשבון, כמו כפתור יציאה או קישור שאפשר ללחוץ עליו. הגישה הזו מאפשרת למשתמשים להתנתק מתי שהם רוצים, או להישאר מחוברים ולשמור את פידי הנתונים שלהם זמינים בקלות לפעם הבאה שהם ניגשים לאפליקציה שלכם.

מידע על טוקנים

בקטע הזה מתוארים האסימונים שבהם נעשה שימוש ב-AuthSub עבור ActionScript. ברוב המקרים, לא תצטרכו לדעת את המידע הזה.

כל טוקן אימות ספציפי לנתונים הבאים:

  • היקף שירות Google
  • חשבון Google של המשתמש
  • אפליקציית לקוח

נתוני האסימון מבטיחים שרק אפליקציית הצד השלישי שצוינה תוכל לבקש נתונים, ושהבקשה תוגבל לנתונים מהיקף ההרשאות וחשבון המשתמש שצוינו.

רק טוקן אחד יכול להיות תקף בכל רגע נתון לשילוב הזה של היקף, משתמש ולקוח. אפליקציית אינטרנט צריכה לבקש טוקן חדש בכל פעם שהיא זקוקה לגישה לשירות חדש של Google עבור משתמש מסוים. היקף הגישה שמכוסה על ידי האסימון תלוי בשירות Google, שעשוי להגביל את הגישה לסוגים מסוימים של נתונים או פעילות, כמו גישה לקריאה בלבד.

אפשר להשתמש באסימון שמוחזר על ידי AuthSub לממשק ActionScript כמה פעמים שצריך עד שהוא מבוטל. האחריות לניהול משך החיים של האסימון מוטלת על האפליקציה, תוך שמירה על איזון בין אבטחה לנוחות. ‫Google ממליצה לבקש טוקן חדש בכל פעם שמתחילים סשן חדש.

יכול להיות שחלק משירותי Google יאפשרו גישה רק לאפליקציות אינטרנט שרשומות ומשתמשות באסימונים מאובטחים. שירותים כאלה לא תומכים ב-AuthSub ל-ActionScript. כדי להשתמש בטוקנים מאובטחים, הארגון שלכם צריך לרשום אישור SSL ב-Google ולחתום על כל הבקשות לפידים האלה של נתונים.

חזרה למעלה