ActionScript での AuthSub の使用

このドキュメントでは、Flash アプリケーションまたは Silverlight アプリケーションから Google の AuthSub 認証システムを使用する方法について説明します。

: Google の ウェブベースのアプリケーション向けアカウント認証サービスである AuthSub にすでに精通している場合は、ActionScript 用 AuthSub のコンセプトが非常に類似していることがわかります。基盤となる実装は異なりますが、クライアント アプリケーション デベロッパーにとって、その違いは重要ではありません。一部のドキュメントでは、区別が不要なコンテキストで、ActionScript 用 AuthSub を「AuthSub」と略して表記しています。

ActionScript 用 AuthSub インターフェースを使用すると、Flash または Silverlight アプリケーションは、ユーザーに代わって保護された Google Data API フィードに対して認証を行うことができます。高いレベルのセキュリティを維持するため、このインターフェースにより、ユーザーのアカウント ログイン情報を処理することなく、認証トークンを取得できます。

ActionScript 用 AuthSub は、JavaScript 用 AuthSub のバリエーションです。JavaScript 用の AuthSub と同様に、Google 以外のドメインでホストされているウェブページからクライアント アプリケーションを認証するためのクロスドメイン メソッドを提供します。認証サービスが別のドメイン(www.google.com ではなく accounts.googleapis.com)に存在し、外部サイトからそのドメインへのアクセスを許可する crossdomain.xml ファイルを提供している点が、標準の AuthSub と異なります。

すべての Authentication サービス API の使用に関する説明については、Google Accounts API グループもご覧ください。

オーディエンス

このドキュメントは、Google サービスにアクセスする Flash または Silverlight のウェブ アプリケーションを開発しているプログラマーを対象としています。

このドキュメントは、Google Data APIs プロトコルAuthSub インターフェースの背後にある一般的な考え方を理解していることを前提としています。また、ActionScript でプログラミングする方法を理解していることも前提としています。

対応している環境

ActionScript 用 AuthSub は現在、Firefox 1.5 以降と Internet Explorer 6.0 以降で、Flash 9.0 以降または Silverlight 2.0 以降とともにサポートされています。

ActionScript 用 AuthSub の仕組み

ウェブ アプリケーション、Google 認証サービス、Google データサービス間の通信の仕組みの概要は次のとおりです。

  1. ユーザーに代わって Google Data サービスにアクセスするには、ウェブ アプリケーションに有効な認証トークンが必要です。通常、アプリケーションはこのトークンを Cookie に保存します。そのような Cookie が存在しない場合、ウェブ アプリケーションは AuthSub を介してトークンを取得する必要があります。トークンを取得するために、ウェブ アプリケーションは、アクセスするサービスを指定して、認証サービスに対して AuthSub for ActionScript ログイン呼び出しを行います。
  2. ウェブ アプリケーションからリクエストを受信すると、認証サービスはユーザーを [アクセス リクエスト] ページにリダイレクトします。このページでは、ユーザーに Google アカウントへのログインを求め、Google サービスへのアクセスを許可するか拒否するかを尋ねます。
  3. ユーザーは、ウェブ アプリケーションへのアクセスを許可するか拒否するかを決定します。ユーザーがアクセスを拒否すると、ウェブ アプリケーションに戻るのではなく、Google のページにリダイレクトされます。
  4. ユーザーが正常にログインしてアクセス権を付与すると、認証サービスは、元の呼び出しを行ったウェブ アプリケーションの URL にユーザーをリダイレクトします。リダイレクトは、クエリ パラメータを介して指定されたサービスの認証トークンを配信します。アプリケーションは、ウェブ アプリケーションのドメインで、ユーザーのブラウザに Cookie としてトークンを保存する必要があります。トークンは取り消されるまで有効です。(トークンを取り消すタイミングについては、トークンについてのセクションをご覧ください)。
  5. ウェブ アプリケーションは Google Data サービスに接続し、サービスに送信する各リクエストとともに認証トークンを送信します。
  6. Google Data サービスがトークンを認識すると、リクエストされたデータが提供されます。

ActionScript インターフェースの AuthSub の使用

ActionScript 用 AuthSub(AuthSubAS)は、Google Data API を使用する Flash(または Silverlight)アプリケーション用のクロスドメイン AuthSub エンドポイントを提供します。

AuthSubAS は、google.com にある AuthSub エンドポイントのミラーを提供します。また、Flash(または Silverlight)がこれらのエンドポイントにアクセスできるようにする crossdomain.xml ファイルも提供します。たとえば、エンドポイント AuthSubSessionToken は、https://accounts.googleapis.com/accounts/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(PicasaWeb。この例では後でアクセスします)のポリシーを読み込んでいます。

  2. 1 回限りのトークンをリクエストします。

    AuthSub プロセスの最初のステップは、AuthSub エンドポイントから 1 回限りのトークンをリクエストすることです。アプリでは、次のように 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 サービスのドキュメントを確認してください。スコープは URL のように見えます。サービスを識別する単純な URL の場合もあれば、読み取り専用アクセスを制限するなど、より制限されたアクセスを指定する場合もあります。サービスでスコープを選択できる場合は、可能な限り最も狭いスコープのトークンをリクエストします。たとえば、Google カレンダーのデータフィードにアクセスするには、'http://www.google.com/calendar' ではなく 'http://www.google.com/calendar/feeds' スコープを使用します。

    ヒント:

    • ユーザーが手動でログイン プロセスを開始するよう促すログイン ボタンなどのユーザー入力メカニズムを提供することを強くおすすめします。ユーザーの操作を待たずに、読み込み直後に確認してリダイレクトすると、ユーザーがページにアクセスしたときに最初に表示されるのは Google のログインページになります。ユーザーがログインしないことを選択した場合、Google はユーザーをページに戻しません。そのため、ユーザーはページにアクセスしようとしたものの、リダイレクトされて戻ってこなかったと認識します。このシナリオは、ユーザーにとって混乱を招き、不満につながる可能性があります。
    • ユーザーの複数の Google サービスにアクセスする必要があるアプリは、新しいサービスごとに新しいトークンをリクエストする必要があります(各サービスには異なるスコープがあるため)。

  3. 認証トークンをリクエストします。

    AuthSubRequest エンドポイントは、ユーザーのブラウザの URL を http://yourWebAppUrl?token=singleUseToken に設定することで、使い捨てトークンをアプリケーションに返します。アプリケーションが 1 回限りのトークンを受け取ったら、そのトークンを複数回使用できる(有効期間の長い)トークンと交換する必要があります。このトークンは、Google データフィードに対するリクエストを行うために使用できます。そのためには、1 回限りのトークンを使用して AuthSubSessionToken メソッドを呼び出します。

    アプリは、読み込み時に URL の 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)"

    Photos サービスの 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. ログアウト ボタンやクリック可能なリンクなど、手動ログアウト機能を提供することをおすすめします。このアプローチにより、ユーザーはログアウトするタイミングを自由に選択できます。また、ログイン状態を維持して、次回アプリにアクセスする際にデータフィードを簡単に利用することもできます。

トークンについて

このセクションでは、ActionScript 用の AuthSub で使用されるトークンについて説明します。ほとんどの場合、この情報を知る必要はありません。

各認証トークンは、次のデータに固有のものです。

  • Google サービス スコープ
  • ユーザーの Google アカウント
  • クライアント アプリケーション

トークンデータにより、指定されたサードパーティ製アプリケーションのみがデータをリクエストでき、リクエストは指定されたスコープとユーザー アカウントのデータに限定されます。

このスコープ、ユーザー、クライアントの組み合わせに対して有効なトークンは、一度に 1 つのみです。ウェブ アプリケーションは、特定のユーザーの新しい Google サービスにアクセスする必要があるたびに、新しいトークンをリクエストする必要があります。トークンでカバーされるアクセス権の範囲は Google サービスによって異なります。Google サービスは、読み取り専用アクセスなど、特定の種類のデータやアクティビティへのアクセスを制限する場合があります。

ActionScript インターフェースの AuthSub によって返されたトークンは、取り消されるまで必要な回数だけ使用できます。トークンの有効期間を管理し、セキュリティと利便性のバランスを取るのは、アプリケーションの責任です。新しいセッションが開始されるたびに新しいトークンをリクエストすることをおすすめします。

一部の Google サービスでは、登録済みの安全なトークンを使用しているウェブ アプリケーションのみがアクセスを許可される場合があります。このようなサービスでは、ActionScript 用の AuthSub はサポートされていません。安全なトークンを使用するには、組織が Google に SSL 証明書を登録し、それらのデータフィードに対するすべてのリクエストに署名する必要があります。

トップへ戻る