OAuth 2.0 para apps de TV e de dispositivo com entrada limitada

Este documento explica como implementar a autorização OAuth 2.0 para acessar as APIs do Google por meio de aplicativos executados em dispositivos como TVs, consoles de jogos e impressoras. Mais especificamente, esse fluxo foi projetado para dispositivos que não têm acesso a um navegador ou recursos de entrada limitados.

O OAuth 2.0 permite que os usuários compartilhem dados específicos com um aplicativo, mantendo a privacidade de nomes de usuário, senhas e outras informações. Por exemplo, um aplicativo de TV pode usar o OAuth 2.0 para receber permissão para selecionar um arquivo armazenado no Google Drive.

Como os aplicativos que usam esse fluxo são distribuídos para dispositivos individuais, presume-se que os aplicativos não podem manter segredos. Eles podem acessar as APIs do Google enquanto o usuário está presente no app ou quando o app está em execução em segundo plano.

Alternativas

Se você estiver escrevendo um aplicativo para uma plataforma como Android, iOS, macOS, Linux ou Windows (incluindo a plataforma universal do Windows) que tenha acesso ao navegador e aos recursos de entrada completos, use o fluxo do OAuth 2.0 para aplicativos de dispositivos móveis e de desktop. Use esse fluxo mesmo que seu app seja uma ferramenta de linha de comando sem uma interface gráfica.

Se você apenas quiser fazer login dos usuários com as Contas do Google deles e usar o token de ID do JWT para receber informações básicas de perfil do usuário, consulte Fazer login em TVs e dispositivos de entrada limitados.

Pré-requisitos

Ativar as APIs do projeto

Qualquer aplicativo que chame APIs do Google precisa ativá-las no API Console.

Para ativar uma API para um projeto, faça o seguinte:

  1. Open the API Library no Google API Console.
  2. If prompted, select a project, or create a new one.
  3. A API Library lista todas as APIs disponíveis, agrupadas por família de produtos e popularidade. Se a API que você quer ativar não estiver visível na lista, use a pesquisa para encontrá-la ou clique em Ver tudo na família de produtos a que ela pertence.
  4. Selecione aquela que você quer habilitar e clique no botão Ativar.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Criar credenciais de autorização

Qualquer aplicativo que usa o OAuth 2.0 para acessar as APIs do Google precisa ter credenciais de autorização que identifiquem o aplicativo para o servidor OAuth 2.0 do Google. As etapas a seguir explicam como criar credenciais para o projeto. Seus aplicativos podem usar as credenciais para acessar as APIs que você ativou nesse projeto.

  1. Go to the Credentials page.
  2. Clique em Criar credenciais > ID do cliente OAuth.
  3. Selecione o tipo de aplicativo de TVs e dispositivos de entrada limitada.
  4. Nomeie seu cliente OAuth 2.0 e clique em Criar.

Identificar escopos de acesso

Os escopos permitem que o aplicativo solicite acesso apenas aos recursos necessários e que os usuários controlem o nível de acesso que concedem ao aplicativo. Portanto, pode haver uma relação inversa entre o número de escopos solicitados e a probabilidade de consentimento do usuário.

Antes de começar a implementar a autorização OAuth 2.0, recomendamos que você identifique os escopos que seu app precisará de permissão para acessar.

Veja a lista de escopos permitidos de apps ou dispositivos instalados.

Como conseguir tokens de acesso do OAuth 2.0

Mesmo que seu aplicativo seja executado em um dispositivo com recursos de entrada limitados, os usuários precisam ter acesso separado a um dispositivo com recursos de entrada mais completos para concluir esse fluxo de autorização. O fluxo tem as seguintes etapas:

  1. Seu aplicativo envia uma solicitação ao servidor de autorização do Google que identifica os escopos que seu aplicativo solicitará permissão para acessar.
  2. O servidor responde com várias informações usadas nas etapas subsequentes, como um código do dispositivo e um código de usuário.
  3. Você exibe informações que o usuário pode inserir em um dispositivo separado para autorizar o app.
  4. Seu aplicativo começa a pesquisar o servidor de autorização do Google para determinar se o usuário autorizou seu aplicativo.
  5. O usuário alterna para um dispositivo com recursos de entrada mais avançados, inicia um navegador da Web, navega para o URL exibido na etapa 3 e insere um código que também é exibido na etapa 3. O usuário pode então conceder (ou negar) acesso ao seu aplicativo.
  6. A próxima resposta à solicitação de pesquisa contém os tokens necessários para que o aplicativo autorize as solicitações em nome do usuário. Se o usuário tiver recusado o acesso ao aplicativo, a resposta não conterá tokens.

A imagem abaixo ilustra esse processo:

O usuário faz login em um dispositivo separado que tenha um navegador

As seções a seguir explicam essas etapas em detalhes. Considerando a variedade de recursos e ambientes de execução que os dispositivos podem ter, os exemplos mostrados neste documento usam o utilitário de linha de comando curl. Esses exemplos devem ser fáceis de portar para várias linguagens e ambientes de execução.

Etapa 1: solicitar códigos de dispositivo e usuário

Nesta etapa, o dispositivo envia uma solicitação HTTP POST ao servidor de autorização do Google, em https://oauth2.googleapis.com/device/code, que identifica seu aplicativo, bem como os escopos de acesso que seu aplicativo quer acessar em nome do usuário. É necessário recuperar esse URL do documento de descoberta usando o valor de metadados device_authorization_endpoint. Inclua os seguintes parâmetros de solicitação HTTP:

Parâmetros
client_id Obrigatório

O ID de cliente do aplicativo. Esse valor está em API Console Credentials page.

scope Obrigatório

Uma lista de escopos delimitada por espaço que identifica os recursos que seu aplicativo pode acessar em nome do usuário. Esses valores informam a tela de consentimento que o Google exibe ao usuário. Consulte a lista de escopos permitidos para dispositivos ou apps instalados.

Os escopos permitem que o aplicativo solicite acesso apenas aos recursos necessários e que os usuários controlem o nível de acesso que concedem ao aplicativo. Assim, há uma relação inversa entre o número de escopos solicitados e a probabilidade de consentimento do usuário.

Exemplos

O snippet a seguir mostra um exemplo de solicitação:

POST /device/code HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=client_id&scope=email%20profile

Este exemplo mostra um comando curl para enviar a mesma solicitação:

curl -d "client_id=client_id&scope=email%20profile" \
     https://oauth2.googleapis.com/device/code

Etapa 2: gerenciar a resposta do servidor de autorização

O servidor de autorização retornará uma das seguintes respostas:

Resposta de sucesso

Se a solicitação for válida, sua resposta será um objeto JSON contendo as seguintes propriedades:

Propriedades
device_code Um valor que o Google atribui exclusivamente para identificar o dispositivo que executa o app que está solicitando a autorização. O usuário autorizará esse dispositivo a partir de outro com recursos de entrada mais avançados. Por exemplo, um usuário pode usar um laptop ou smartphone para autorizar um app executado em uma TV. Nesse caso, o device_code identifica a TV.

Esse código permite que o dispositivo que executa o app determine com segurança se o usuário concedeu ou negou acesso.

expires_in Período em que device_code e user_code são válidos. Se, nesse momento, o usuário não concluir o fluxo de autorização e seu dispositivo também não pesquisar para recuperar informações sobre a decisão do usuário, talvez seja necessário reiniciar esse processo da etapa 1.
interval O tempo, em segundos, que seu dispositivo deve aguardar entre as solicitações de pesquisa. Por exemplo, se o valor for 5, seu dispositivo precisará enviar uma solicitação de pesquisa ao servidor de autorização do Google a cada cinco segundos. Veja mais detalhes na etapa 3.
user_code Um valor que diferencia maiúsculas de minúsculas e identifica os escopos a que o aplicativo está solicitando acesso. A interface do usuário instruirá o usuário a inserir esse valor em um dispositivo separado com recursos de entrada mais avançados. Em seguida, o Google usa o valor para exibir o conjunto correto de escopos ao solicitar que o usuário conceda acesso ao seu aplicativo.
verification_url Um URL em que o usuário precisa navegar, em um dispositivo separado, para inserir o user_code e conceder ou negar o acesso ao seu aplicativo. Sua interface do usuário também exibirá esse valor.

O snippet a seguir mostra um exemplo de resposta:

{
  "device_code": "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",
  "user_code": "GQVQ-JKEC",
  "verification_url": "https://www.google.com/device",
  "expires_in": 1800,
  "interval": 5
}

A cota excedeu a resposta

Se as solicitações de código do dispositivo excederem a cota associada ao seu ID do cliente, você receberá uma resposta 403 contendo o seguinte erro:

{
  "error_code": "rate_limit_exceeded"
}

Nesse caso, use uma estratégia de retirada para reduzir a taxa de solicitações.

Etapa 3: exibir o código do usuário

Exiba o verification_url e o user_code recebidos na etapa 2 para o usuário. Os dois valores podem conter qualquer caractere para impressão do conjunto de caracteres ASCII dos EUA. O conteúdo que você exibe ao usuário precisa orientar o usuário a navegar até o verification_url em um dispositivo separado e inserir o user_code.

Projete sua interface do usuário (IU) com as seguintes regras em mente:

  • user_code
    • O user_code precisa ser exibido em um campo que possa lidar com 15 caracteres "W". Em outras palavras, se você conseguir exibir o código WWWWWWWWWWWWWWW corretamente, sua IU será válida. Recomendamos usar esse valor de string ao testar a maneira como user_code é exibido na IU.
    • O user_code diferencia maiúsculas de minúsculas e não deve ser modificado de forma alguma, como alterar a capitalização ou inserir outros caracteres de formatação.
  • verification_url
    • O espaço em que você exibe verification_url precisa ser largo o suficiente para lidar com uma string de URL de 40 caracteres.
    • Não modifique o verification_url de maneira alguma, exceto para remover o esquema para exibição. Se você planeja remover o esquema (por exemplo, https://) do URL por motivos de exibição, verifique se o app pode lidar com as variantes http e https.

Etapa 4: pesquisar o servidor de autorização do Google

Como o usuário usará um dispositivo separado para navegar até o verification_url e conceder (ou negar) acesso, o dispositivo solicitante não será notificado automaticamente quando o usuário responder à solicitação de acesso. Por esse motivo, o dispositivo solicitante precisa pesquisar no servidor de autorização do Google para determinar quando o usuário respondeu à solicitação.

O dispositivo solicitante precisa continuar enviando solicitações de pesquisa até receber uma resposta indicando que o usuário respondeu à solicitação de acesso ou até que os device_code e user_code recebidos na etapa 2 tenham expirado. O interval retornado na etapa 2 especifica o tempo, em segundos, para aguardar entre solicitações.

O URL do endpoint a ser pesquisado é https://oauth2.googleapis.com/token. A solicitação de pesquisa contém os seguintes parâmetros:

Parâmetros
client_id O ID de cliente do aplicativo. Esse valor está em API Console Credentials page.
client_secret A chave secreta do cliente para o client_id fornecido. Esse valor está em API Console Credentials page.
device_code O device_code retornado pelo servidor de autorização na etapa 2.
grant_type Defina esse valor como urn:ietf:params:oauth:grant-type:device_code.

Exemplos

O snippet a seguir mostra um exemplo de solicitação:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=client_id&
client_secret=client_secret&
device_code=device_code&
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code

Este exemplo mostra um comando curl para enviar a mesma solicitação:

curl -d "client_id=client_id&client_secret=client_secret& \
         device_code=device_code& \
         grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code" \
         -H "Content-Type: application/x-www-form-urlencoded" \
         https://oauth2.googleapis.com/token

Etapa 5: o usuário responde à solicitação de acesso

A imagem a seguir mostra uma página semelhante à que os usuários veem ao navegar para a verification_url exibida na etapa 3:

Conectar um dispositivo digitando um código

Depois de inserir o user_code e, se ainda não estiver conectado, fazer login no Google, o usuário verá uma tela de consentimento como a mostrada abaixo:

Exemplo de tela de consentimento para um cliente do dispositivo

Etapa 6: gerenciar respostas para solicitações de sondagem

O servidor de autorização do Google responde a cada solicitação de pesquisa com uma das seguintes respostas:

Acesso concedido

Se o usuário concedeu acesso ao dispositivo (clicando em Allow na tela de consentimento), a resposta conterá um token de acesso e um token de atualização. Os tokens permitem que o dispositivo acesse as APIs do Google em nome do usuário. A propriedade scope na resposta determina quais APIs o dispositivo pode acessar.

Nesse caso, a resposta da API contém os seguintes campos:

Campos
access_token O token que seu aplicativo envia para autorizar uma solicitação de API do Google.
expires_in A vida útil restante do token de acesso em segundos.
refresh_token Um token que pode ser usado para receber um novo token de acesso. Os tokens de atualização são válidos até que o usuário revogue o acesso. Os tokens de atualização são sempre retornados para dispositivos.
scope Os escopos de acesso concedidos pelo access_token expressos como uma lista de strings delimitadas por espaços, que diferenciam maiúsculas de minúsculas.
token_type O tipo de token retornado. No momento, o valor desse campo é sempre definido como Bearer.

O snippet a seguir mostra um exemplo de resposta:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
  "token_type": "Bearer",
  "refresh_token": "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

Os tokens de acesso têm duração limitada. Se o aplicativo precisar de acesso a uma API por um longo período, ele poderá usar o token de atualização para receber um novo token de acesso. Se o aplicativo precisar desse tipo de acesso, ele precisará armazenar o token de atualização para uso posterior.

Acesso negado

Se o usuário se recusar a conceder acesso ao dispositivo, a resposta do servidor terá um código de status de resposta HTTP 403 (Forbidden). A resposta contém o seguinte erro:

{
  "error": "access_denied",
  "error_description": "Forbidden"
}

Autorização pendente

Se o usuário ainda não tiver concluído o fluxo de autorização, o servidor retornará um código de status de resposta HTTP 428 (Precondition Required). A resposta contém o seguinte erro:

{
  "error": "authorization_pending",
  "error_description": "Precondition Required"
}

Pesquisas frequentes

Se o dispositivo enviar solicitações de pesquisa com muita frequência, o servidor retornará um código de status de resposta HTTP 403 (Forbidden). A resposta contém o seguinte erro:

{
  "error": "slow_down",
  "error_description": "Forbidden"
}

Outros erros

O servidor de autorização também retornará erros se a solicitação de pesquisa estiver sem algum parâmetro obrigatório ou tiver um valor de parâmetro incorreto. Essas solicitações geralmente têm um código de status de resposta HTTP 400 (Bad Request) ou 401 (Unauthorized). Esses erros incluem:

Erro Código de status HTTP Descrição
admin_policy_enforced 400 A Conta do Google não pode autorizar um ou mais escopos solicitados devido às políticas do administrador do Google Workspace. Consulte o artigo de ajuda do administrador do Google Workspace em Controlar quais apps internos e de terceiros acessam os dados do Google Workspace para mais informações sobre como um administrador pode restringir o acesso a escopos até que o acesso seja explicitamente concedido ao seu ID do cliente OAuth.
invalid_client 401

O cliente OAuth não foi encontrado. Por exemplo, esse erro ocorrerá se o valor do parâmetro client_id for inválido.

O tipo de cliente OAuth está incorreto. Verifique se o tipo de aplicativo do ID do cliente está definido como Dispositivos de TV e entrada limitada.

invalid_grant 400 O valor do parâmetro code é inválido, já foi reivindicado ou não pode ser analisado.
unsupported_grant_type 400 O valor do parâmetro grant_type é inválido.
org_internal 403 O ID do cliente OAuth na solicitação faz parte de um projeto que limita o acesso a Contas do Google em uma organização do Google Cloud específica. Confirme a configuração do tipo de usuário para seu aplicativo OAuth.

Como chamar APIs do Google

Depois que o aplicativo receber um token de acesso, use-o para fazer chamadas a uma API do Google em nome de uma determinada conta de usuário se os escopos de acesso exigidos pela API tiverem sido concedidos. Para fazer isso, inclua o token de acesso em uma solicitação para a API, incluindo um parâmetro de consulta access_token ou um valor Authorization de cabeçalho HTTP Bearer. Quando possível, o cabeçalho HTTP é preferível, porque as strings de consulta tendem a ser visíveis nos registros do servidor. Na maioria dos casos, você pode usar uma biblioteca de cliente para configurar suas chamadas para as APIs do Google (por exemplo, ao chamar a API Drive Files).

É possível testar todas as APIs do Google e visualizar seus escopos no OAuth 2.0 Playground.

Exemplos de HTTP GET

Uma chamada para o endpoint drive.files (a API Drive Files) que usa o cabeçalho HTTP Authorization: Bearer pode ter a seguinte aparência: É necessário especificar seu próprio token de acesso:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Veja uma chamada para a mesma API para o usuário autenticado usando o parâmetro de string de consulta access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

Exemplos de curl

É possível testar esses comandos com o aplicativo de linha de comando curl. Veja um exemplo que usa a opção de cabeçalho HTTP (preferencial):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Ou, como alternativa, a opção de parâmetro da string de consulta:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Atualização do token de acesso

Os tokens de acesso expiram periodicamente e se tornam credenciais inválidas para uma solicitação de API relacionada. É possível atualizar um token de acesso sem solicitar permissão do usuário (inclusive quando ele não está presente) se você solicitou acesso off-line aos escopos associados ao token.

Para atualizar um token de acesso, o aplicativo envia uma solicitação HTTPS POST para o servidor de autorização do Google (https://oauth2.googleapis.com/token) que inclui os seguintes parâmetros:

Campos
client_id O ID do cliente recebido do API Console.
client_secret A chave secreta do cliente recebida do API Console.
grant_type Conforme definido na especificação do OAuth 2.0, o valor deste campo precisa ser definido como refresh_token.
refresh_token O token de atualização retornado da troca de código de autorização.

O snippet a seguir mostra um exemplo de solicitação:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=your_client_id&
client_secret=your_client_secret&
refresh_token=refresh_token&
grant_type=refresh_token

Contanto que o usuário não tenha revogado o acesso concedido ao aplicativo, o servidor de token retorna um objeto JSON que contém um novo token de acesso. O snippet a seguir mostra um exemplo de resposta:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
  "token_type": "Bearer"
}

Há limites para o número de tokens de atualização que serão emitidos: um limite por combinação cliente/usuário e outro por usuário em todos os clientes. Salve tokens de atualização no armazenamento de longo prazo e continue a usá-los, desde que permaneçam válidos. Se o aplicativo solicitar muitos tokens de atualização, ele poderá atingir esses limites. Nesse caso, os tokens de atualização mais antigos deixarão de funcionar.

Como revogar um token

Em alguns casos, o usuário talvez queira revogar o acesso concedido a um aplicativo. Um usuário pode revogar o acesso acessando as Configurações da conta. Consulte a seção Remover o acesso do site ou app dos sites e apps de terceiros com acesso à sua conta para mais informações.

Também é possível que um aplicativo revogue programaticamente o acesso concedido a ele. A revogação programática é importante nos casos em que um usuário cancela a inscrição, remove um aplicativo ou quando os recursos da API exigidos por um aplicativo são significativamente alterados. Em outras palavras, parte do processo de remoção pode incluir uma solicitação de API para garantir que as permissões concedidas anteriormente ao aplicativo sejam removidas.

Para revogar programaticamente um token, o aplicativo faz uma solicitação para https://oauth2.googleapis.com/revoke e inclui o token como um parâmetro:

curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
        https://oauth2.googleapis.com/revoke?token={token}

O token pode ser de acesso ou de atualização. Se for um token de acesso e tiver um token de atualização correspondente, o token de atualização também será revogado.

Se a revogação for processada, o código de status HTTP da resposta será 200. Para condições de erro, um código de status HTTP 400 é retornado junto com um código de erro.

Escopos permitidos

O fluxo OAuth 2.0 para dispositivos é compatível apenas com os seguintes escopos:

OpenID Connect, Login do Google

  • email
  • openid
  • profile

API Drive

  • https://www.googleapis.com/auth/drive.appdata
  • https://www.googleapis.com/auth/drive.file

API YouTube

  • https://www.googleapis.com/auth/youtube
  • https://www.googleapis.com/auth/youtube.readonly