XPN nas bibliotecas de cliente do protocolo de dados do Google

Aviso: esta página é sobre as APIs mais antigas do Google, as APIs de dados do Google. Relevante apenas para as APIs listadas no diretório das APIs de dados do Google, muitas delas foram substituídas por APIs mais recentes. Para mais informações sobre uma nova API específica, consulte a documentação da nova API. Para informações sobre autorização de solicitações com uma API mais recente, consulte Autenticação e autorização de Contas do Google.

Neste documento, descrevemos como usar as bibliotecas de cliente da API Google Data para se conectar à Autenticação tmp para apps da Web do Google.

A interface tmp permite que um aplicativo baseado na Web acesse um serviço do Google em nome de um usuário. Para manter um alto nível de segurança, a interface tmp permite que o aplicativo receba um token de autenticação sem nunca processar as informações de login da conta do usuário.

As bibliotecas cliente da API de dados do Google fornecem métodos para ajudar você a usar o XPN em seu aplicativo da Web. Especificamente, há métodos para construir o URL de solicitação, adquirir um token de autenticação de uso único, trocar o token de uso único por um token de sessão e assinar a solicitação.

Observação: a biblioteca de cliente JavaScript tem a própria variação de tmp, chamada tmpJS. Para mais informações sobre como usar o XPNJS nos seus aplicativos JavaScript, consulte Como usar a autenticação "tmp" com a biblioteca de cliente JavaScript.

Público-alvo

Este documento é destinado a programadores que querem que seus aplicativos baseados na Web acessem serviços do Google em nome dos usuários, usando as bibliotecas de cliente das APIs de dados do Google.

Ele pressupõe que você esteja familiarizado com a interface do tmp e o processo geral para incorporar o tmpt ao seu aplicativo da Web. Para ver uma descrição completa do protocolo do tmp, consulte Autenticação tmp para aplicativos da Web.

Uso de APIs tmp e Google Data sem as bibliotecas de cliente

Se você quiser que o cliente do app da Web interaja com um serviço de dados do Google usando o XPN como um sistema de autenticação, tudo o que você precisa saber está em Autenticação do tmp para apps da Web. Não é necessário usar as bibliotecas de cliente das APIs de dados do Google se você não quiser.

Veja um resumo de como o aplicativo pode autenticar um usuário usando o XPN:

O seu aplicativo constrói o URL LOGIN apropriado e, em seguida, envia o usuário para esse URL para que ele possa fazer login. O sistema XPN envia o usuário de volta ao URL no seu site especificado e retorna um token de uso único. Seu aplicativo pode trocar esse token por um token de sessão. Em seguida, o aplicativo envia o token no cabeçalho Authorization com cada solicitação que o aplicativo envia ao serviço.

As bibliotecas cliente das APIs de dados do Google simplificam esse processo de autorização ao lidar com vários detalhes para você. Veja neste documento como fazer isso.

Como trabalhar com o XPN e as APIs de dados do Google: exemplos da biblioteca cliente

Esta seção mostra um exemplo do uso dos métodos da biblioteca de cliente das APIs de dados do Google para seguir as etapas descritas na seção "Trabalhar com tmp" da documentação do tmp.

Neste exemplo, estamos integrando a interface tmp em um aplicativo da Web que interage com o Google Agenda (embora você não precise saber nada sobre o Google Agenda para seguir o exemplo). No exemplo, pressupomos que o aplicativo da Web esteja hospedado em example.com.

Decida o tipo de token a ser usado (session=0 ou session=1)

É possível optar por usar tokens de uso único (session=0) ou de sessão (session=1). Este documento usará tokens de sessão, já que eles são mais úteis em aplicativos que fazem várias solicitações de API. Conforme discutido na documentação do XPN, se você decidir usar tokens de sessão no seu aplicativo da Web, precisará gerenciar o armazenamento de tokens por conta própria. Este documento não aborda o gerenciamento de tokens. Observe também que os tokens solicitados com session=0 não podem ser trocados posteriormente (atualizados) para um token de sessão de longa duração.

Decida se quer registrar o aplicativo da Web (secure=0 ou secure=1).

É possível usar o BYOL de três modos diferentes: não registrado, registrado e registrado com segurança encantada. O restante deste documento fará referência à última opção como XPN seguro. Embora o modo não registrado/registrado seja mais simples de configurar do que o XPN seguro, o Google recomenda o uso de tokens seguros para a segurança envolvida deles.

Como se cadastrar

Escolher Registro para aplicativos baseados na Web oferece os seguintes benefícios para seu aplicativo:

  1. Um nível maior de segurança.
  2. ser confiável pelo Google (nenhum aviso é exibido ao usuário na página de autorização do Google)

Registrado com + seguro

Se você optar por XPN seguro, precisará criar uma chave privada RSA de assinatura própria e um par de certificado público, além de registrar seu aplicativo da Web. Consulte Como gerar chaves e certificados para uso com o modo registrado (abaixo) para ver exemplos de como criar certificados X.509.

Determinar o escopo do seu acesso aos dados

Cada serviço do Google define um valor de scope que determina (e possivelmente limita) o acesso de um token aos dados do usuário. Consulte as perguntas frequentes para ver a lista de valores scope disponíveis.

Como decidimos interagir com a API Google Calendar, o scope precisa ser http://www.google.com/calendar/feeds/.

Observação: sempre defina o valor do escopo para o URL mais amplo possível, a menos que você precise de uma restrição mais precisa. Por exemplo, um escopo mais restrito, como scope=http://www.google.com/calendar/feeds/default/allcalendars/full, restringirá o acesso do token apenas ao feed allcalendars/full. Usar scope=http://www.google.com/calendar/feeds/ permitirá o acesso a todos os feeds da Agenda: http://www.google.com/calendar/feeds/*.

Tokens com vários escopos

Para criar tokens que acessam várias APIs de dados do Google, separe cada escopo com um espaço codificado por URL. O exemplo abaixo cria um token que terá acesso aos contatos do Google e aos dados do Google Agenda de um usuário.

scope=http://www.google.com/calendar/feeds/%20http://www.google.com/m8/feeds/

Solicitar um token de autenticação de uso único

Para adquirir um token tmp para um determinado usuário e serviço, seu app precisa redirecionar o usuário ao URL AuthSubRequest, que solicita o login na Conta do Google. Para mais informações sobre o URL AuthSubRequest, consulte a Autenticação XMPP para aplicativos da Web.

Para criar o URL AuthSubRequest no seu aplicativo, use o código abaixo para cada biblioteca de cliente:

Java

import com.google.gdata.client.*;

String nextUrl = "http://www.example.com/RetrieveToken.jsp";
String scope = "http://www.google.com/calendar/feeds/";
boolean secure = false;  // set secure=true to request secure AuthSub tokens
boolean session = true;
String authSubUrl = AuthSubUtil.getRequestUrl(nextUrl, scope, secure, session);

Se você quiser autenticar usuários no seu domínio do G Suite:

import com.google.gdata.client.*;

String hostedDomain = "example.com";
String nextUrl = "http://www.example.com/RetrieveToken.jsp";
String scope = "http://www.google.com/calendar/feeds/";
boolean secure = false;  // set secure=true to request AuthSub tokens
boolean session = true;
String authSubUrl = AuthSubUtil.getRequestUrl(hostedDomain, nextUrl, scope, secure, session);

.NET

using Google.GData.Client;

String nextUrl = "http://www.example.com/RetrieveToken.aspx";
String scope = "http://www.google.com/calendar/feeds/";
bool secure = false; // set secure=true to request secure AuthSub tokens
bool session = true;
String authSubUrl = AuthSubUtil.getRequestUrl(nextUrl, scope, secure, session);

Se você quiser autenticar usuários no seu domínio do G Suite:

using Google.GData.Client;

String hostedDomain = "example.com";
String nextUrl = "http://www.example.com/RetrieveToken.aspx";
String scope = "http://www.google.com/calendar/feeds/";
bool secure = false; // set secure=true to request secure AuthSub tokens
bool session = true;
String authSubUrl = AuthSubUtil.getRequestUrl(hostedDomain, nextUrl, scope, secure, session);

PHP

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_AuthSub');

$nextUrl = 'http://www.example.com/RetrieveToken.php';
$scope = 'http://www.google.com/calendar/feeds/';
$secure = 0;  // set $secure=1 to request secure AuthSub tokens
$session = 1;
$authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($nextUrl, $scope, $secure, $session);

Se você quiser autenticar usuários no seu domínio do G Suite:

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_AuthSub');

$hostedDomain = 'example.com';
$nextUrl = 'http://www.example.com/RetrieveToken.php';
$scope = 'http://www.google.com/calendar/feeds/';
$secure = 0;  // set $secure=1 to request secure AuthSub tokens
$session = 1;
$authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($nextUrl, $scope, $secure, $session) . '&hd=' . $hostedDomain;

Python

import gdata.auth

next = 'http://www.example.com/RetrieveToken.pyc'
scope = 'http://www.google.com/calendar/feeds/'
secure = False  # set secure=True to request secure AuthSub tokens
session = True
auth_sub_url = gdata.auth.GenerateAuthSubRequestUrl(next, scope, secure=secure, session=session)

Se você quiser autenticar usuários no seu domínio do G Suite:

import gdata.auth

hosted_domain = 'example.com'
next = 'http://www.example.com/RetrieveToken.pyc'
scope = 'http://www.google.com/calendar/feeds/'
secure = False  # set secure=True to request secure AuthSub tokens
session = True
auth_sub_url = gdata.auth.GenerateAuthSubRequestUrl(next, scope, secure=secure, session=session, domain=hosted_domain)

Depois de construir o URL "next", seu aplicativo poderá usá-lo de várias maneiras para enviar o usuário ao gerenciador AuthSubRequest. A abordagem mais comum é exibir uma página informando ao usuário que ele precisa seguir um link para autorizar o aplicativo a acessar a Conta do Google e anexar o URL da solicitação ao link. Por exemplo, você pode gerar a seguinte string no seu app da Web:

String authorizationUrl =
        "<p>MyApp needs access to your Google Calendar account to read your Calendar feed. " +
        "To authorize MyApp to access your account, <a href=\"" + authSubUrl + "\">log in to your account</a>.</p>";

O usuário segue o link para a página do tmp no Google e faz login. O sistema IFRAME redireciona o usuário para seu aplicativo usando o "próximo" URL fornecido.

Extrair o token de uso único

Quando o Google redireciona de volta para seu aplicativo, o token é anexado ao URL "next" como um parâmetro de consulta. No caso dos exemplos acima, depois que o usuário faz login, o Google redireciona para um URL como http://www.example.com/RetrieveToken?token=DQAADKEDE. Seu aplicativo deve extrair o valor do token do parâmetro de consulta do URL dele.

Se seu aplicativo definir um cookie de autenticação no navegador do usuário antes de enviá-lo ao sistema XPN, quando o Google redirecionar de volta para o URL "próximo", seu aplicativo poderá ler o cookie de autenticação para reconhecer qual usuário chegou a esse URL. Você pode usar esse cookie para associar um ID de usuário em seu aplicativo com o token XPN recuperado do Google.

As bibliotecas de cliente oferecem métodos convenientes para extrair o token de uso único:

Java

String singleUseToken = AuthSubUtil.getTokenFromReply(httpServletRequest.getQueryString());

.NET

String singleUseToken = Request.QueryString["token"];
// or
String singleUseToken = AuthSubUtil.getTokenFromReply(new Uri(Request.QueryString));

PHP

$singleUseToken = $_GET['token'];

Python

current_url = 'http://' + req.hostname + req.unparsed_uri
# Unlike the other calls, extract_auth_sub_token_from_url() will create an AuthSubToken or SecureAuthSubToken object.
# Use str(single_use_token) to return the token's string value.
single_use_token = gdata.auth.extract_auth_sub_token_from_url(current_url)

Se você estiver usando o tmp seguro, defina sua chave privada RSA para que um SecureAuthSubToken seja criado:

f = open('/path/to/yourRSAPrivateKey.pem')
rsa_key = f.read()
f.close()
current_url = 'http://' + req.hostname + req.unparsed_uri
# Unlike the other calls, extract_auth_sub_token_from_url() will create an AuthSubToken or SecureAuthSubToken object.
# Use str(single_use_token) to return the token's string value.
single_use_token = gdata.auth.extract_auth_sub_token_from_url(current_url, rsa_key=rsa_key)

Solicitar um token de sessão

O token recuperado do URL é sempre de uso único. A próxima etapa é fazer upgrade desse token para um token de sessão de longa duração usando o URL AuthSubSessionToken, conforme descrito na documentação completa do Authentication Autenticador para aplicativos da Web. Se você estiver usando o XPN seguro, precisará definir sua chave privada RSA antes de fazer a troca. Veja alguns exemplos que usam cada uma das bibliotecas de cliente:

Java

import com.google.gdata.client.*;
import com.google.gdata.client.calendar.*;

String sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, null);

CalendarService calendarService = new CalendarService("google-ExampleApp-v1.0");
calendarService.setAuthSubToken(sessionToken, null);

// ready to interact with Calendar feeds

Para um tmp seguro, transmita sua chave privada RSA para exchangeForSessionToken em vez de colar null:

import com.google.gdata.client.*;
import com.google.gdata.client.calendar.*;

java.security.PrivateKey privateKey =
    AuthSubUtil.getPrivateKeyFromKeystore("AuthSubExample.jks", "privKeyPa$$word", "AuthSubExample", "privKeyPa$$word");
String sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, privateKey);

CalendarService calendarService = new CalendarService("google-ExampleApp-v1.0");
calendarService.setAuthSubToken(sessionToken, privateKey);

// ready to interact with Calendar feeds

.NET

using Google.GData.Client;
using Google.GData.Calendar;

String sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, null).ToString();

GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "google-ExampleApp-v1.0");
authFactory.Token = (String) sessionToken;

CalendarService calendarService = new CalendarService(authFactory.ApplicationName);
calendarService.RequestFactory = authFactory;

// ready to interact with Calendar feeds

Para um tmp seguro, transmita sua chave privada RSA para exchangeForSessionToken em vez de colar null:

using Google.GData.Client;
using Google.GData.Calendar;

protected AsymmetricAlgorithm getRsaKey()
{
  X509Certificate2 cert = new X509Certificate2("C:/MyAspSite/test_cert.pfx", "privKeyPa$$word");
  RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider;
  return privateKey;
}

AsymmetricAlgorithm rsaKey = getRsaKey();
String sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, rsaKey).ToString();

GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "google-ExampleApp-v1.0");
authFactory.Token = (String) sessionToken;
authFactory.PrivateKey = rsaKey;

CalendarService calendarService = new CalendarService(authFactory.ApplicationName);
calendarService.RequestFactory = authFactory;

// ready to interact with Calendar feeds

PHP

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_Calendar');

$sessionToken = Zend_Gdata_AuthSub::getAuthSubSessionToken($singleUseToken);

// Create a Calendar service object and set the session token for subsequent requests
$calendarService = new Zend_Gdata_Calendar(null, 'google-ExampleApp-v1.0');
$calendarService->setAuthSubToken($sessionToken);

// ready to interact with Calendar feeds

Para um tmp seguro, a troca exige que você configure um Zend_Gdata_HttpClient e defina sua chave privada RSA usando setAuthSubPrivateKeyFile():

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_Calendar');

$client = new Zend_Gdata_HttpClient();
$client->setAuthSubPrivateKeyFile('/path/to/myrsakey.pem', null, true);
$sessionToken = Zend_Gdata_AuthSub::getAuthSubSessionToken($singleUseToken, $client);

$calendarService = new Zend_Gdata_Calendar($client, 'google-ExampleApp-v1.0');
$calendarService->setAuthSubToken($sessionToken);

// ready to interact with Calendar feeds

Python

import gdata.calendar
import gdata.calendar.service

calendar_service = gdata.calendar.service.CalendarService()
calendar_service.UpgradeToSessionToken(single_use_token)  # calls gdata.service.SetAuthSubToken() for you

# ready to interact with Calendar feeds

Observação: o processo é o mesmo para o tmp seguro, desde que você tenha usado gdata.auth.extract_auth_sub_token_from_url(url, rsa_key=rsa_key) para extrair o token de uso único.

Observação: quando você usa o tmp seguro, sua chave privada não é enviada pela rede. As bibliotecas de cliente enviam a assinatura exclusiva gerada ao assinar a solicitação com sua chave, não a própria chave.

Usar o token de sessão

É possível usar o token de sessão para autenticar solicitações ao servidor colocando o token no cabeçalho Authorization, conforme descrito na documentação do tmp.

Depois de definir o token de sessão, você pode usar as chamadas da biblioteca de cliente padrão das APIs de dados do Google para interagir com o serviço, sem precisar pensar no token. Para mais detalhes, consulte a documentação da biblioteca de cliente e o guia do desenvolvedor das APIs de dados do Google sobre o serviço e a linguagem com que você está interagindo.

Como recuperar informações sobre um token de sessão

Se você quiser testar se o cliente e o servidor concordam com os parâmetros do token, transmita o token para o gerenciador AuthSubTokenInfo, que retorna um conjunto de pares de nome-valor contendo informações sobre o token.

Java

Map<String, String> tokenInfo = AuthSubUtil.getTokenInfo(sessionToken, null);

Se você estiver usando o tmp seguro, transmita sua chave privada RSA:

Map<String, String> tokenInfo = AuthSubUtil.getTokenInfo(sessionToken, privateKey);

.NET

Dictionary<String, String> tokenInfo = AuthSubUtil.GetTokenInfo(sessionToken, null);

Se você estiver usando o tmp seguro, transmita sua chave privada RSA:

Dictionary<String, String> tokenInfo = AuthSubUtil.GetTokenInfo(sessionToken, privateKey);

PHP

$tokenInfo = Zend_Gdata_AuthSub::getAuthSubTokenInfo($sessionToken);

Se você estiver usando o XPN seguro, transmita seu Zend_Gdata_HttpClient para que a solicitação seja assinada com sua chave privada RSA:

$tokenInfo = Zend_Gdata_AuthSub::getAuthSubTokenInfo($sessionToken, $client);

Python

token_info = calendar_service.AuthSubTokenInfo()

Revogar um token de sessão

Os tokens de sessão tmp não expiram. Seu cliente pode armazenar o token de sessão pelo tempo necessário.

Portanto, quando o cliente terminar de usar o token de sessão, ele poderá revogá-lo usando o gerenciador AuthSubRevokeToken, conforme descrito na documentação do tmp.

Por exemplo, se você quiser gerenciar tokens de modo semelhante a uma sessão tradicional, seu cliente poderá obter um token no início da sessão de um usuário e revogá-lo no final da sessão.

Para revogar um token, use o código abaixo em cada biblioteca de cliente:

Java

AuthSubUtil.revokeToken(sessionToken, null);

Se você estiver usando o tmp seguro, transmita sua chave privada RSA:

AuthSubUtil.revokeToken(sessionToken, privateKey);

.NET

AuthSubUtil.revokeToken(sessionToken, null);

Se você estiver usando o tmp seguro, transmita sua chave privada RSA:

AuthSubUtil.revokeToken(sessionToken, privateKey);

PHP

$wasRevoked = Zend_Gdata_AuthSub::AuthSubRevokeToken($sessionToken);

Se você estiver usando o XPN seguro, transmita seu Zend_Gdata_HttpClient para que a solicitação seja assinada com sua chave privada RSA:

$wasRevoked = Zend_Gdata_AuthSub::AuthSubRevokeToken($sessionToken, $client);

Python

calendar_service.RevokeAuthSubToken()

Outros recursos e amostras

Voltar ao início

Gerar um certificado público e uma chave privada de assinatura própria para uso com o XPN seguro

A chave privada é usada para gerar uma assinatura, que precisa ser incluída em cada solicitação. A chave pública incorporada ao certificado é usada pelo Google para verificar a assinatura. A chave pública precisa ser uma Chave RSA de 1.024 bits codificada em um certificado X.509 no formato PEM. O certificado será enviado ao Google no momento do registro.

As seções a seguir fornecem exemplos de como gerar chaves e certificados usando duas ferramentas específicas: o utilitário OpenSSL e o utilitário keytool do Java.

Esses exemplos não são específicos das APIs de dados do Google. Você pode usar os mesmos utilitários para gerar chaves para qualquer finalidade.

Os exemplos consideram que sua empresa se chama My_Company e está localizada em Mountain View, Califórnia, EUA, com o nome de domínio example.com.

Como gerar chaves usando o OpenSSL

Para criar um par de chaves RSA e o certificado correspondente, use o seguinte comando:

# Generate the RSA keys and certificate
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj \
  '/C=US/ST=CA/L=Mountain View/CN=www.example.com' -keyout \
  myrsakey.pem -out /tmp/myrsacert.pem

Aviso: incluir o parâmetro -nodes cria uma chave privada sem senha para protegê-la. No entanto, considere a possibilidade de omitir esse parâmetro para aumentar a segurança.

O parâmetro -sha1 especifica que a chave será usada para gerar assinaturas SHA1.

O parâmetro -subj especifica a identidade do aplicativo que o certificado representa.

O parâmetro -keyout especifica o arquivo que vai conter as chaves. Esse arquivo contém informações sensíveis e precisa ser protegido e não compartilhado com ninguém.

O parâmetro -out especifica o arquivo que contém o certificado no formato PEM, que pode ser enviado ao Google durante o registro.

Como gerar chaves para o cliente .NET

O framework .NET não entende chaves ou certificados armazenados no formato PEM. Portanto, é necessário realizar uma etapa adicional depois que você tiver criado o arquivo .pem:

openssl pkcs12 -export -in test_cert.pem -inkey myrsacert.pem -out myrsacert.pfx -name "Testing Certificate"

Esta etapa gera um arquivo PFX com base na chave privada e no certificado. Esse arquivo pode ser importado para a biblioteca de cliente .NET para assinar digitalmente as solicitações feitas às APIs de dados do Google.

Como gerar chaves para o cliente Java

O cliente Java aceita chaves privadas no formato PKCS#8. Depois de gerar uma chave/certificado usando as instruções acima, crie um arquivo .pk8 a partir do arquivo .pem gerado:

openssl pkcs8 -in myrsakey.pem -topk8 -nocrypt -out myrsakey.pk8

Se preferir, use o armazenamento de chaves Java e o utilitário keytool para criar um par de chaves RSA e o certificado correspondente. Use o comando a seguir:

# Generate the RSA keys and certificate
keytool -genkey -v -alias Example -keystore ./Example.jks\
  -keyalg RSA -sigalg SHA1withRSA\
  -dname "CN=www.example.com, OU=Engineering, O=My_Company, L=Mountain  View, ST=CA, C=US"\
  -storepass changeme -keypass changeme

Aviso: "changeme" não é uma senha forte. Este é apenas um exemplo.

O parâmetro -dname especifica a identidade do aplicativo que o certificado representa. O parâmetro -storepass especifica a senha para proteger o keystore. O parâmetro -keypass especifica a senha para proteger a chave privada.

Para gravar o certificado em um arquivo que pode ser usado na ferramenta ManageDomains, use o seguinte comando:

# Output the public certificate to a file
keytool -export -rfc -keystore ./Example.jks -storepass changeme \
  -alias Example -file mycert.pem

Voltar ao início