在 Action 中使用 AuthSub

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

注意:如果您已熟悉 AuthSub(Google 的适用于 Web 应用的帐号身份验证服务),就会发现 AuthSub for Action 在概念上非常相似。底层实现是不同的,但区别对客户端应用开发者而言并不重要。在某些文档中,由于区分不相关,我们用适用于 AuthSub 的 Action 简称为“AuthSub”。

AuthSub for Action 界面可让 Flash 或 Silverlight 应用代表用户向受保护的 Google Data API Feed 进行身份验证。为了保持高级别的安全性,应用可通过该接口获取身份验证令牌,而无需处理用户的登录信息。

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

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

观众

本文面向的是开发访问 Google 服务的 Flash 或 Silverlight 网络应用的程序员。

本文档假定您了解 Google Data API 协议AuthSub 接口的一般概念。此外,本教程还假定您已知道如何使用 ActionScript 进行编程。

受支持的环境

Firefox 1.5 及更高版本和 Internet Explorer 6.0 及更高版本以及 Flash 9.0 或更高版本、Silverlight 2.0 或更高版本均支持适用于 Action 的 AuthSub。

适用于 Action 的 AuthSub 的工作原理

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

  1. 要代表用户访问 Google 数据服务,Web 应用必须具有有效的身份验证令牌。通常,应用将此令牌存储在 Cookie 中;如果没有这样的 Cookie,则 Web 应用必须通过 AuthSub 获取此令牌。为了获取令牌,Web 应用会对 Authentication 服务进行用于 Action 的 AuthSub 登录调用,并指定要访问的服务。
  2. 收到 Web 应用的请求后,Authentication 服务会将用户重定向到“访问请求”页面。此页面会提示用户登录其 Google 帐号,并要求用户授予或拒绝其 Google 服务的访问权限。
  3. 用户决定是授予还是拒绝 Web 应用的访问权限。如果用户拒绝授予访问权限,则会定向到 Google 页面,而不是 Web 应用。
  4. 如果用户成功登录并授予访问权限,Authentication 服务会将用户重定向回进行原始调用的 Web 应用网址。重定向通过查询参数传递指定服务的身份验证令牌。应用应在 Web 应用网域下,将令牌作为 Cookie 存储在用户的浏览器中。令牌在撤销之前一直有效。(如需了解有关何时撤消令牌的建议,请参阅令牌简介部分。)
  5. Web 应用会与 Google 数据服务联系,并将身份验证令牌以及发送到服务的每个请求一并发送。
  6. 如果 Google 数据服务识别出令牌,它会提供请求的数据。

使用适用于身份验证的 AuthSub 接口

适用于 Action 的 AuthSub(即 AuthSubAS)为使用 Google Data API 的 Flash(或 Silverlight)应用提供跨网域 AuthSub 端点。

AuthSubAS 提供了在 google.com 上找到的 AuthSub 端点的镜像,以及一个允许 Flash(或 Silverlight)额外访问这些端点的 crossdomain.xml 文件。例如,可通过访问 https://accounts.googleapis.com/accounts/AuthSubSessionToken 来使用端点 AuthSubSessionToken

以下步骤详细介绍了获取身份验证令牌并使用该令牌从 Flash 应用访问 Google 服务的过程。

  1. 设置跨网域政策

    若要以跨网域方式使用 Flash,则必须通过要访问的每个外部网域的政策对其进行初始化。为此,请为每个网域调用 Action 方法 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 Web,稍后将访问示例)的政策。

  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 服务的文档。范围看起来像网址,可以是一个简单的网址,用于标识服务,也可以指定更严格的访问权限,例如限制对只读的访问。当服务提供范围选择时,尽可能请求范围最严格的令牌。例如,要访问 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)"

    相册服务的 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 用于执行 Action 的令牌。在大多数情况下,您无需知道此信息。

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

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

令牌数据可确保只有指定的第三方应用才能请求数据,且请求仅限于来自指定范围和用户帐号的数据。

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

由 AuthSub for Action 接口返回的令牌可以根据需要使用多次,直到令牌被撤消为止。令牌的生命周期由应用管理,兼顾安全性与便利性。Google 建议每次启动新会话时都请求新令牌。

某些 Google 服务可能只允许已注册并使用安全令牌的 Web 应用访问。此类服务不支持适用于 Action 的 AuthSub。要使用安全令牌,您的组织必须向 Google 注册 SSL 证书并签署针对这些数据 Feed 的所有请求。

返回页首