Como usar XPN em ActionScript

Este documento descreve como usar o sistema de autenticação XPN do Google de um aplicativo Flash ou Silverlight.

Observação: se você já conhece o XPN, o serviço de autenticação de conta do Google para aplicativos baseados na Web, vai ver que o XPN para ActionScript é conceitualmente muito semelhante. A implementação subjacente é diferente, mas as diferenças não são importantes para você como desenvolvedor de aplicativos clientes. Em alguns termos da documentação, em contextos em que a distinção é irrelevante, nos referimos ao IFRAME para "script" (ou "jpeg")

A interface do OAuth para ActionScript permite que aplicativos Flash ou Silverlight sejam autenticados em feeds protegidos da API de dados do Google em nome de um usuário. Para manter um alto nível de segurança, a interface permite que o aplicativo receba um token de autenticação sem nunca processar as informações de login da conta do usuário.

O tmp no ActionScript é uma variante do tmp para JavaScript. Assim como o tmp para JavaScript, ele fornece um método de vários domínios para os aplicativos cliente serem autenticados a partir de uma página da Web hospedada em um domínio que não é do Google. Ele é diferente do XPN padrão porque o serviço de autenticação reside em um domínio diferente (accounts.googleapis.com, em vez de www.google.com) e fornece um arquivo crossdomain.xml que permite o acesso a esse domínio de sites externos.

Consulte também o grupo da API Google Accounts para ver como usar todas as APIs de serviço do Authentication.

Público-alvo

Este documento é destinado a programadores que estão desenvolvendo aplicativos da web Flash ou Silverlight que acessam serviços do Google.

Neste documento, pressupomos que você entende as ideias gerais por trás do protocolo das APIs de dados do Google e da interface tmp. Você também precisa saber como programar em ActionScript.

Ambientes compatíveis

No momento, o tmp para ActionScript é compatível com o Firefox 1.5 e superior e com o Internet Explorer 6.0 ou superior, com Flash 9.0 ou superior ou Silverlight 2.0 ou superior.

Como o OAuth para o snippet funciona

Veja um resumo rápido de como a comunicação funciona entre um aplicativo da Web, o serviço de autenticação do Google e um serviço de dados do Google:

  1. Para acessar um serviço de dados do Google em nome de um usuário, o aplicativo da Web precisa ter um token de autenticação válido. Normalmente, os aplicativos armazenam esse token em um cookie. Se esse cookie não existir, o aplicativo da web deverá adquirir o token via tmp. Para adquirir um token, o aplicativo da web faz uma chamada de login do OAuth para o serviço de autenticação, especificando o serviço a ser acessado.
  2. Ao receber a solicitação do aplicativo da Web, o serviço de autenticação redireciona o usuário para uma página "Solicitação de acesso". Essa página solicita que o usuário faça login na Conta do Google e peça que ele conceda ou negue o acesso ao serviço.
  3. O usuário decide se quer conceder ou negar acesso ao aplicativo da Web. Se o usuário negar o acesso, ele será direcionado para uma página do Google, e não para o aplicativo da Web.
  4. Se o usuário fizer login e conceder acesso, o serviço do Authentication vai redirecionar o usuário de volta ao URL do aplicativo da Web que fez a chamada original. O redirecionamento envia um token de autenticação ao serviço especificado usando um parâmetro de consulta. O aplicativo deve armazenar o token como um cookie no navegador do usuário, no domínio do aplicativo da Web. O token é válido até ser revogado. Consulte a seção Sobre tokens para ver orientações sobre quando revogar tokens.
  5. O aplicativo da Web entra em contato com o serviço de Dados do Google e envia o token de autenticação junto com cada solicitação enviada ao serviço.
  6. Se o serviço de dados do Google reconhecer o token, ele fornecerá os dados solicitados.

Como usar a interface Cmd para ActionScript

O XPN para ActionScript, ou IFRAMEAS, fornece um endpoint Domínios diferentes para aplicativos Flash (ou Silverlight) que usam APIs de dados do Google.

O tmpas fornece um espelho dos endpoints do ISBN encontrados em google.com, com um arquivo crossdomain.xml adicional que permite que o Flash (ou o Silverlight) acesse esses endpoints. Por exemplo, o endpoint tmpSessionToken pode ser usado acessando https://accounts.googleapis.com/accounts/tmpSessionToken.

As etapas a seguir mostram o processo de recebimento de um token de autenticação e de como usá-lo para acessar um serviço do Google em um aplicativo Flash.

  1. Configure as políticas de vários domínios.

    Para usar o Flash em vários domínios, ele precisa ser inicializado com uma política para cada domínio externo que será acessado. Para fazer isso, invoque o método Security.loadPolicyFile(policy) do ActionScript para cada domínio, desta forma:

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

    Ver amostra completa

    Observe que estamos carregando a política para accounts.googleapis.com (tmpAS) e para photos.googleapis.com/data ( PicasaWeb, que o exemplo acessa mais tarde).

  2. Solicitar um token de uso único.

    A primeira etapa no processo XPN é solicitar um token de uso único do endpoint tmp. Seu aplicativo precisa fazer isso invocando uma chamada para o endpoint AuthSubRequest, desta maneira:

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

    Ver amostra completa

    Esse método exige um valor de scope. Cada serviço do Google define o escopo do acesso que ele permite, e você precisa referenciar esse escopo na solicitação de token. Para determinar o valor do escopo a ser usado, consulte a documentação do Serviço do Google que você quer acessar. O escopo parece um URL. Pode ser um URL simples que identifica o serviço ou pode especificar acesso mais restrito, como limitar o acesso para somente leitura. Quando o serviço oferece uma opção de escopo, solicite o token com escopo mais restrito possível. Por exemplo, para acessar os feeds de dados do Google Agenda, use o escopo 'http://www.google.com/calendar/feeds', não 'http://www.google.com/calendar'.

    Dicas:

    • Recomendamos que você forneça um botão de login ou outro mecanismo de entrada do usuário para solicitar que o usuário inicie o processo de login manualmente. Se, em vez disso, você verificar e redirecionar imediatamente após o carregamento, sem esperar pela interação do usuário, a primeira coisa que o usuário vê ao chegar na sua página é uma página de login do Google. Se o usuário decidir não fazer login, o Google não o redirecionará de volta para sua página. Assim, do ponto de vista do usuário, ele tentou visitar sua página, mas foi mandado para longe e nunca mais voltou. Isso pode ser confuso e frustrante para os usuários.
    • Os aplicativos que precisam acessar mais de um serviço do Google para um usuário precisam solicitar um novo token para cada serviço novo, já que cada serviço tem um escopo diferente.

  3. Solicite um token de autenticação.

    O endpoint AuthSubRequest vai retornar um token de uso único ao seu aplicativo, definindo o URL do navegador do usuário como http://yourWebAppUrl?token=singleUseToken. Depois que o aplicativo receber o token de uso único, ele precisará trocá-lo por um token de vários usos (de longa duração), que poderá ser usado para fazer solicitações em feeds de dados do Google. Para fazer isso, chame o método AuthSubSessionToken com o token de uso único.

    O aplicativo precisa verificar o parâmetro token no URL quando ele é carregado:

        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 ... }

    Ver amostra completa

    Se o token for encontrado, ele vai chamar um método como getLongLivedToken, que invoca o endpoint 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);
          }
    
    

    Ver amostra completa

    Um método como o gerenciador onGetTokenResult precisa salvar o token retornado:

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

    Ver amostra completa

    Dicas:

    • É altamente recomendável que seu aplicativo armazene o token de longo prazo em um cookie e os verifique antes da verificação de token de curto prazo. Isso impede que os usuários precisem acessar a página de confirmação do IFRAME sempre que quiserem usar o aplicativo.

  4. Como usar um token de autenticação.

    Para usar o token de autenticação, anexe-o por meio de um cabeçalho Authorization a todas as solicitações feitas a um serviço do Google:

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

    Exemplo no serviço de fotos em 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'));
    
    

    Ver amostra completa

  5. O Google recomenda disponibilizar um recurso de logout manual, como um botão de saída ou um link clicável. Essa abordagem dá aos usuários a opção de sair quando quiserem ou permanecer conectado e manter os feeds de dados convenientemente disponíveis na próxima vez que acessarem o aplicativo.

Sobre tokens

Esta seção descreve os tokens usados por XPN para ActionScript. Na maioria dos contextos, essas informações não são necessárias.

Cada token de autenticação é específico para os seguintes dados:

  • Escopo do serviço do Google
  • Conta do Google do usuário
  • Aplicativo cliente

Os dados do token garantem que somente o aplicativo de terceiros especificado possa solicitar dados e que a solicitação seja limitada a dados do escopo e da conta de usuário especificados.

Somente um token para essa combinação de escopo, usuário e cliente pode ser válido por vez. Um aplicativo da Web precisa solicitar um novo token sempre que precisar de acesso a um novo serviço do Google para um determinado usuário. O escopo do acesso coberto pelo token depende do serviço do Google, que pode limitar o acesso a determinados tipos de dados ou atividades, como o acesso somente leitura.

O token retornado pela interface do IFRAME para ActionScript pode ser usado quantas vezes forem necessárias até que seja revogado. Cabe ao seu aplicativo gerenciar a vida útil do token, equilibrando a segurança com conveniência. O Google recomenda solicitar um novo token sempre que uma nova sessão for iniciada.

Alguns Serviços do Google podem permitir o acesso somente de apps da Web registrados e que usam tokens seguros. Para esses serviços, não há suporte ao XPN para o ActionScript. Para usar tokens seguros, sua organização precisa registrar um certificado SSL no Google e assinar todas as solicitações para esses feeds de dados.

Voltar ao início