在 ActionScript 中使用 AuthSub

本文档介绍了如何从 Flash 或 Silverlight 应用中使用 Google 的 AuthSub 身份验证系统。

注意:如果您已熟悉 AuthSub(Google 针对基于 Web 的应用的账号身份验证服务),您会发现 ActionScript 版 AuthSub 在概念上非常相似。底层实现有所不同,但作为客户端应用开发者,您无需关注这些差异。在某些文档中,如果区分无关紧要,我们会将 ActionScript 版 AuthSub 简称为“AuthSub”。

借助适用于 ActionScript 的 AuthSub 接口,Flash 或 Silverlight 应用可以代表用户向受保护的 Google Data API Feed 进行身份验证。为了保持高安全级别,该接口使应用能够获取身份验证令牌,而无需处理用户的账号登录信息。

适用于 ActionScript 的 AuthSub 是适用于 JavaScript 的 AuthSub 的变体。与 JavaScript 的 AuthSub 类似,它提供了一种跨网域方法,供客户端应用从托管在非 Google 网域上的网页进行身份验证。它与标准 AuthSub 的不同之处在于,身份验证服务位于不同的网域(accounts.googleapis.com 而不是 www.google.com),并提供一个 crossdomain.xml 文件,允许从外部网站访问该网域。

如需了解如何使用所有身份验证服务 API,另请参阅 Google Accounts API Group

受众群体

本文档面向正在开发访问 Google 服务的 Flash 或 Silverlight Web 应用的程序员。

本文档假定您了解 Google Data API 协议AuthSub 接口背后的基本原理。本文还假定您已了解如何使用 ActionScript 进行编程。

受支持的环境

目前,Firefox 1.5 及更高版本和 Internet Explorer 6.0 及更高版本支持 ActionScript 的 AuthSub,但需要安装 Flash 9.0 及更高版本或 Silverlight 2.0 及更高版本。

ActionScript 版 AuthSub 的工作原理

下面简要介绍了 Web 应用、Google 身份验证服务和 Google 数据服务之间的通信方式:

  1. 若要代表用户访问 Google Data 服务,Web 应用必须具有有效的身份验证令牌。通常,应用会将此令牌存储在 Cookie 中;如果不存在此类 Cookie,Web 应用必须通过 AuthSub 获取令牌。为了获取令牌,Web 应用会向身份验证服务发出 AuthSub for ActionScript 登录调用,并指定要访问的服务。
  2. 在收到来自 Web 应用的请求后,身份验证服务会将用户重定向到“访问权限申请”页面。此页面会提示用户登录其 Google 账号,并要求用户授予或拒绝访问其 Google 服务的权限。
  3. 用户决定是否授予对 Web 应用的访问权限。 如果用户拒绝授予访问权限,系统会将用户定向到 Google 页面,而不是返回到 Web 应用。
  4. 如果用户成功登录并授予访问权限,身份验证服务会将用户重定向回发出原始调用的 Web 应用网址。重定向通过查询参数为指定服务提供身份验证令牌。应用应将令牌作为 Cookie 存储在用户浏览器中,位于 Web 应用的网域下。令牌在被撤消之前一直有效。(如需有关何时撤消令牌的建议,请参阅关于令牌部分。)
  5. Web 应用会与 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(示例稍后会访问 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');

    查看完整示例

    此方法需要 scope 值。每项 Google 服务都会定义其允许的访问权限范围,您需要在令牌请求中引用该范围。如需确定要使用的范围值,请查看您要访问的 Google 服务的文档。范围看起来像一个网址;它可以是标识服务的简单网址,也可以指定更严格的访问权限,例如将访问权限限制为只读。如果服务提供多种范围选择,请请求范围尽可能小的令牌。例如,如需访问 Google 日历的数据 Feed,请使用 'http://www.google.com/calendar/feeds' 范围,而不是 'http://www.google.com/calendar'

    提示

    • 我们强烈建议您提供登录按钮或其他用户输入机制,以提示用户手动开始登录流程。如果您在加载后立即检查并重定向,而不等待用户互动,那么用户到达您的网页后首先看到的是 Google 登录页面。如果用户决定不登录,Google 就不会将他们重定向回您的网页;因此,从用户的角度来看,他们尝试访问您的网页,但被发送到其他网页,并且再也没有被发送回来。这种情况可能会让用户感到困惑和沮丧。
    • 需要访问用户的多项 Google 服务的应用必须为每项新服务请求一个新令牌(因为每项服务的范围都不同)。

  3. 请求身份验证令牌。

    AuthSubRequest 端点会将用户浏览器的网址设置为 http://yourWebAppUrl?token=singleUseToken,从而向您的应用返回一次性令牌。应用收到一次性令牌后,必须将该令牌换成可多次使用(长期有效)的令牌,然后才能使用该令牌针对 Google 数据 Feed 发出请求。为此,请使用一次性令牌调用 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)"

    适用于 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. Google 建议提供手动退出功能,例如退出按钮或可点击的链接。这种方法让用户可以选择随时退出,也可以选择保持登录状态,以便下次访问您的应用时可以方便地查看数据 Feed。

令牌简介

本部分介绍了 AuthSub 为 ActionScript 使用的令牌。在大多数情况下,您无需了解此信息。

每个身份验证令牌都特定于以下数据:

  • Google 服务范围
  • 用户的 Google 账号
  • 客户端应用

令牌数据可确保只有指定的第三方应用可以请求数据,并且请求仅限于指定范围和用户账号中的数据。

对于范围、用户和客户端的这种组合,一次只能有一个令牌有效。Web 应用每次需要访问特定用户的新 Google 服务时,都必须请求新令牌。令牌涵盖的访问权限范围取决于 Google 服务,该服务可以选择限制对特定类型的数据或活动的访问权限,例如只读访问权限。

AuthSub 为 ActionScript 接口返回的令牌可以根据需要多次使用,直到被撤消为止。令牌的生命周期由应用自行管理,需要在安全性和便利性之间取得平衡。Google 建议您在每次启动新会话时都请求新令牌。

某些 Google 服务可能仅允许已注册并使用安全令牌的 Web 应用访问。此类服务不支持 ActionScript 的 AuthSub。若要使用安全令牌,贵组织必须向 Google 注册 SSL 证书,并对这些数据源的所有请求进行签名。

返回页首