在 ActionScript 中使用 AuthSub

本文說明如何從 Flash 或 Silverlight 應用程式使用 Google 的 AuthSub 驗證系統。

注意:如果您已熟悉 AuthSub (Google 的網頁應用程式帳戶驗證服務),就會發現 ActionScript 的 AuthSub 在概念上非常相似。底層實作方式不同,但對用戶端應用程式開發人員而言,這些差異並不重要。在某些說明文件中,如果區別不重要,我們會簡稱 ActionScript 的 AuthSub 為「AuthSub」。

Flash 或 Silverlight 應用程式可透過 ActionScript 介面的 AuthSub,代表使用者向受保護的 Google Data API 資訊動態饋給進行驗證。為維持高安全等級,應用程式可透過這個介面取得驗證權杖,完全不必處理使用者的帳戶登入資訊。

ActionScript 適用的 AuthSub 是 JavaScript 適用的 AuthSub 變體。與 JavaScript 適用的 AuthSub 類似,這個方法也提供跨網域驗證機制,讓用戶端應用程式從非 Google 網域代管的網頁進行驗證。與標準 AuthSub 不同的是,驗證服務位於不同網域 (accounts.googleapis.com,而非 www.google.com),並提供 crossdomain.xml 檔案,允許從外部網站存取該網域。

如要討論如何使用所有 Authentication 服務 API,請參閱 Google 帳戶 API 群組

觀眾

本文適用於開發會存取 Google 服務的 Flash 或 Silverlight 網頁應用程式的程式設計師。

本文假設您瞭解 Google Data APIs 通訊協定AuthSub 介面背後的概念。同時假設您知道如何使用 ActionScript 編寫程式。

支援的環境

目前 Firefox 1.5 以上版本和 Internet Explorer 6.0 以上版本支援 ActionScript 的 AuthSub,但須搭配 Flash 9.0 以上版本或 Silverlight 2.0 以上版本。

ActionScript 的 AuthSub 運作方式

以下簡要說明網路應用程式、Google 驗證服務和 Google 資料服務之間的通訊方式:

  1. 如要代表使用者存取 Google 資料服務,網路應用程式必須具備有效的驗證權杖。應用程式通常會將這個權杖儲存在 Cookie 中;如果沒有這類 Cookie,網路應用程式就必須透過 AuthSub 取得權杖。如要取得權杖,網頁應用程式會向 Authentication 服務發出 AuthSub for ActionScript 登入呼叫,並指定要存取的服務。
  2. 驗證服務收到網頁應用程式的要求後,會將使用者重新導向至「存取要求」頁面。這個頁面會提示使用者登入 Google 帳戶,並要求他們授予或拒絕存取 Google 服務的權限。
  3. 使用者可決定是否要授予網頁應用程式存取權。如果使用者拒絕存取權,系統會將他們導向 Google 網頁,而非返回網頁應用程式。
  4. 如果使用者成功登入並授予存取權,驗證服務會將使用者重新導向至發出原始呼叫的網頁應用程式網址。重新導向會透過查詢參數,為指定服務提供驗證權杖。應用程式應將權杖儲存為使用者瀏覽器中網頁應用程式網域下的 Cookie。憑證在撤銷前有效。(如需撤銷權杖時機的建議,請參閱「關於權杖」一節)。
  5. 網路應用程式會與 Google Data 服務聯絡,並在傳送給服務的每個要求中附上驗證權杖。
  6. 如果 Google Data 服務可辨識權杖,就會提供要求的資料。

使用 ActionScript 介面的 AuthSub

AuthSub for ActionScript (又稱 AuthSubAS) 可為使用 Google Data API 的 Flash (或 Silverlight) 應用程式提供跨網域的 AuthSub 端點。

AuthSubAS 提供 google.com 上的 AuthSub 端點鏡像,並額外提供 crossdomain.xml 檔案,讓 Flash (或 Silverlight) 存取這些端點。舉例來說,您可以透過存取 https://accounts.googleapis.com/accounts/AuthSubSessionToken,使用 AuthSubSessionToken 端點。

以下步驟將逐步說明如何取得驗證權杖,並使用該權杖從 Flash 應用程式存取 Google 服務。

  1. 設定跨網域政策。

    如要跨網域使用 Flash,必須針對要存取的每個外部網域,使用政策進行初始化。如要這麼做,請為每個網域叫用 ActionScript 方法 Security.loadPolicyFile(policy),如下所示:

    <?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 (Picasa 網路相簿,範例稍後會存取) 的政策。

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

    查看完整範例

    這個方法需要 scope 值。每項 Google 服務都會定義允許的存取範圍,您需要在權杖要求中參照該範圍。如要判斷要使用的範圍值,請參閱您想存取的 Google 服務說明文件。範圍看起來像網址,可能是識別服務的簡單網址,也可能指定更嚴格的存取權,例如限制為唯讀存取權。如果服務提供多種範圍,請盡可能要求範圍最嚴格的權杖。舉例來說,如要存取 Google 日曆的資料動態消息,請使用 'http://www.google.com/calendar/feeds' 範圍,而非 'http://www.google.com/calendar'

    提示

    • 強烈建議您提供登入按鈕或其他使用者輸入機制,提示使用者手動啟動登入程序。如果改為在載入後立即檢查並重新導向,而不等待使用者互動,那麼使用者抵達網頁後,首先看到的會是 Google 登入頁面。如果使用者決定不登入,Google 就不會將他們帶回您的網頁;因此從使用者的角度來看,他們嘗試造訪您的網頁,但被送走後就再也沒回來。這種情況可能會讓使用者感到困惑和沮喪。
    • 如果應用程式需要存取使用者的多項 Google 服務,必須為每項新服務要求新的權杖 (因為每項服務的範圍都不同)。

  3. 要求驗證權杖。

    AuthSubRequest 端點會將使用者瀏覽器的網址設為 http://yourWebAppUrl?token=singleUseToken,藉此將一次性權杖傳回應用程式。應用程式收到一次性權杖後,必須將權杖換成可多次使用的長期權杖,才能用來對 Google 資料動態饋給提出要求。如要這麼做,請使用一次性權杖呼叫 AuthSubSessionToken 方法。

    應用程式載入時,應檢查網址中的 token 參數:

        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 處理常式的方法應儲存傳回的權杖:

        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 範例:

          // 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 for ActionScript 使用的權杖。在大多數情況下,您不需要知道這項資訊。

每個驗證權杖都專屬於下列資料:

  • Google 服務範圍
  • 使用者的 Google 帳戶
  • 用戶端應用程式

權杖資料可確保只有指定的第三方應用程式可以要求資料,且要求僅限於指定範圍和使用者帳戶的資料。

在任何時間,這個範圍、使用者和用戶端組合只能有一個有效權杖。網頁應用程式每次需要存取特定使用者的 Google 服務時,都必須要求新的權杖。權杖涵蓋的存取範圍取決於 Google 服務,服務可能會選擇限制特定類型資料或活動的存取權,例如唯讀存取權。

ActionScript 介面的 AuthSub 傳回的權杖可重複使用,直到遭到撤銷為止。應用程式必須自行管理權杖的生命週期,同時兼顧安全性和便利性。Google 建議每次啟動新工作階段時,都要求新的符記。

部分 Google 服務可能只允許已註冊且使用安全權杖的網路應用程式存取。這類服務不支援 ActionScript 的 AuthSub。如要使用安全權杖,貴機構必須向 Google 註冊 SSL 憑證,並簽署所有資料動態饋給的要求。

返回頁首