Neste documento, explicamos como os aplicativos instalados em dispositivos como smartphones, tablets e computadores usam endpoints OAuth 2.0 do Google para autorizar o acesso às APIs do Google.
O OAuth 2.0 permite que os usuários compartilhem dados específicos com um aplicativo, mantendo a privacidade dos nomes de usuários, senhas e outras informações. Por exemplo, um aplicativo pode usar o OAuth 2.0 para receber permissão dos usuários para armazenar arquivos nos drives do Google.
Os apps instalados são distribuídos para dispositivos individuais, e presume-se que esses apps não possam manter secrets. Eles podem acessar as APIs do Google enquanto o usuário está presente no app ou quando ele está em execução em segundo plano.
Esse fluxo de autorização é semelhante ao usado para aplicativos de servidor da Web. A principal diferença é que os apps instalados precisam abrir o navegador do sistema e fornecer um URI de redirecionamento local para processar as respostas do servidor de autorização do Google.
Alternativas
No caso de apps para dispositivos móveis, é recomendável usar o Login do Google para Android ou iOS. As bibliotecas de cliente do Login do Google gerenciam a autenticação e a autorização do usuário. Elas podem ser mais simples de implementar do que o protocolo de nível inferior descrito aqui.
Para apps executados em dispositivos que não são compatíveis com um navegador do sistema ou que têm recursos de entrada limitados, como TVs, consoles de jogos, câmeras ou impressoras, consulte OAuth 2.0 para TVs e dispositivos ou Login em TVs e dispositivos de entrada limitada.
Bibliotecas e amostras
Recomendamos as seguintes bibliotecas e amostras para ajudar você a implementar o fluxo do OAuth 2.0 descrito neste documento:
- Biblioteca AppAuth para Android
- Biblioteca AppAuth para iOS
- OAuth para apps: amostras do Windows
Pré-requisitos
Ativar as APIs do projeto
Qualquer aplicativo que chame APIs do Google precisa ativar essas APIs no API Console.
Para ativar uma API para um projeto, faça o seguinte:
- Open the API Library no Google API Console.
- If prompted, select a project, or create a new one.
- 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 à qual ela pertence.
- Selecione aquela que você quer habilitar e clique no botão Ativar.
- If prompted, enable billing.
- 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.
- Go to the Credentials page.
- Clique em Criar credenciais > ID do cliente OAuth.
- As seções abaixo descrevem os tipos de cliente e os métodos de redirecionamento aceitos pelo servidor de autorização do Google. Escolha o tipo de cliente recomendado para seu aplicativo, nomeie seu cliente OAuth e defina os outros campos no formulário conforme apropriado.
Esquema de URI personalizado (Android, iOS, UWP)
Um esquema de URI personalizado é recomendado para apps Android, iOS e da Plataforma Universal do Windows (UWP, na sigla em inglês).
Android
- Selecione o tipo de aplicativo Android.
- Digite um nome para o cliente OAuth. Esse nome é exibido no Credentials page do projeto para identificar o cliente.
- Insira o nome do pacote do seu app Android. Esse valor é definido no
atributo
package
do elemento<manifest>
no arquivo de manifesto do app. - Insira a impressão digital do certificado de assinatura SHA-1 da distribuição de apps.
- Se o app usa a Assinatura de apps do Google Play, copie a impressão digital SHA-1 da página de assinatura de apps do Play Console.
- Se você gerencia suas próprias chaves de assinatura e repositório de chaves, use o utilitário keytool (em inglês) incluído no Java para imprimir as informações de certificado em um formato legível. Copie o
valor
SHA1
na seçãoCertificate fingerprints
da saída de keytool. Para mais informações, consulte Como autenticar seu cliente na documentação das APIs do Google para Android.
- Clique em Criar.
iOS
- Selecione o tipo de aplicativo iOS.
- Digite um nome para o cliente OAuth. Esse nome é exibido no Credentials page do projeto para identificar o cliente.
- Insira o identificador do pacote do seu app. O ID do pacote é o valor da chave CFBundleIdentifier no arquivo de recursos da lista de propriedades de informações do app (info.plist). Geralmente, ele é exibido no painel "Geral" ou "Assinaturas e recursos" do editor de projetos do Xcode. O ID do pacote também é exibido na seção "Informações gerais" da página "Informações do app" no site App Store Connect da Apple.
- (Opcional)
Digite o código da App Store se ele estiver publicado na App Store da Apple. O ID da loja é uma string numérica incluída em todos os URLs da App Store da Apple.
- Abra o app da Apple App Store no seu dispositivo iOS ou iPadOS.
- Procure seu app.
- Selecione o botão "Compartilhar" (quadrado e símbolo de seta para cima).
- Selecione Copiar link.
- Cole o link em um editor de texto. O ID da App Store é a parte final do URL.
Exemplo:
https://apps.apple.com/app/google/id284815942
- (Opcional)
Insira o ID da equipe. Consulte Localizar o ID da equipe na documentação da conta de desenvolvedor da Apple para mais informações.
- Clique em Criar.
UWP;
- Selecione o tipo de aplicativo Plataforma Universal do Windows.
- Digite um nome para o cliente OAuth. Esse nome é exibido no Credentials page do projeto para identificar o cliente.
- Insira o ID da Microsoft Store de 12 caracteres. Esse valor pode ser encontrado no Microsoft Partner Center, na página Identidade do app, na seção "Gerenciamento de apps".
- Clique em Criar.
Para apps UWP, o esquema de URI personalizado não pode ter mais de 39 caracteres.
Endereço IP de loopback (macOS, Linux, Windows desktop)
Para receber o código de autorização usando esse URL, o aplicativo precisa detectar no servidor da Web local. Isso é possível em muitas plataformas, mas não em todas. No entanto, se sua plataforma for compatível, esse será o mecanismo recomendado para conseguir o código de autorização.
Quando o app recebe a resposta de autorização, para melhorar a usabilidade, ele exibe uma página HTML que instrui o usuário a fechar o navegador e retornar ao app.
Uso recomendado | Apps para macOS, Linux e computador (mas não para a Plataforma Universal Windows) |
Valores de formulário | Defina o tipo de aplicativo como App para computador. |
Copiar/colar manualmente
Identificar escopos de acesso
Os escopos permitem que o aplicativo solicite apenas acesso aos recursos necessários, além de permitir que os usuários controlem o nível de acesso que concedem ao aplicativo. Assim, 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.
O documento Escopos da API OAuth 2.0 contém uma lista completa de escopos que você pode usar para acessar as APIs do Google.
Como conseguir tokens de acesso do OAuth 2.0
As etapas a seguir mostram como seu aplicativo interage com o servidor OAuth 2.0 do Google para receber o consentimento de um usuário para executar uma solicitação de API em nome do usuário. O aplicativo precisa ter esse consentimento para que possa executar uma solicitação da API do Google que exija autorização do usuário.
Etapa 1: gerar um verificador de código e um desafio
O Google é compatível com o protocolo Proof Key for Code Exchange (PKCE, na sigla em inglês) para tornar o fluxo de app instalado mais seguro. Um verificador de código exclusivo é criado para cada solicitação de autorização, e o valor transformado dele, chamado "code_challenge", é enviado ao servidor de autorização para receber o código de autorização.
Criar o verificador de código
Um code_verifier
é uma string aleatória criptográfica de alta entropia usando os caracteres
não reservados [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~", com comprimento mínimo de 43 caracteres
e comprimento máximo de 128 caracteres.
O verificador de código deve ter entropia suficiente para tornar impraticável adivinhar o valor.
Criar o desafio de código
Há dois métodos para criar o desafio de código compatíveis.
Métodos de geração de desafios de código | |
---|---|
S256 (recomendado) | O desafio do código é o hash SHA256 codificado em Base64URL do verificador de código.
|
simples | O desafio de código tem o mesmo valor que o verificador de código gerado acima.
|
Etapa 2: envie uma solicitação ao servidor OAuth 2.0 do Google
Para receber autorização do usuário, envie uma solicitação ao servidor de autorização do Google em
https://accounts.google.com/o/oauth2/v2/auth
. Esse endpoint processa a pesquisa da sessão ativa,
autentica o usuário e recebe o consentimento dele. O endpoint só pode ser acessado por SSL e
recusa conexões HTTP (não SSL).
O servidor de autorização é compatível com os seguintes parâmetros de string de consulta para aplicativos instalados:
Parâmetros | |||||||
---|---|---|---|---|---|---|---|
client_id |
Obrigatório
O ID do cliente do aplicativo. Esse valor pode ser encontrado no API Console Credentials page. |
||||||
redirect_uri |
Obrigatório
Determina como o servidor de autorização do Google envia uma resposta para seu app. Existem várias opções de redirecionamento disponíveis para os apps instalados, e você terá configurado as credenciais de autorização com um método de redirecionamento específico em mente. O valor precisa corresponder exatamente a um dos URIs de redirecionamento autorizados para o cliente OAuth 2.0, que você configurou no Credentials pagedo API Console. Se esse valor não corresponder a um URI autorizado, você receberá um erro A tabela abaixo mostra o valor de parâmetro
|
||||||
response_type |
Obrigatório
Determina se o endpoint do OAuth 2.0 do Google retorna um código de autorização. Defina o valor do parâmetro como |
||||||
scope |
Obrigatório
Uma lista de escopos delimitada por espaços que identificam 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. Os escopos permitem que o aplicativo solicite apenas acesso aos recursos necessários, além de permitir que os usuários controlem o nível de acesso que concedem ao aplicativo. Portanto, há uma relação inversa entre o número de escopos solicitados e a probabilidade de receber o consentimento do usuário. |
||||||
code_challenge |
Recomendável
Especifica um |
||||||
code_challenge_method |
Recomendável
Especifica qual método foi usado para codificar um |
||||||
state |
Recomendável
Especifica qualquer valor de string que seu aplicativo usa para manter o estado entre a
solicitação de autorização e a resposta do servidor de autorização.
O servidor retorna o valor exato que você envia como um par Esse parâmetro pode ser usado para várias finalidades, como direcionar o usuário ao
recurso correto no aplicativo, enviar valores de uso único e atenuar a falsificação de solicitações entre sites. Como o |
||||||
login_hint |
Opcional
Se o aplicativo souber qual usuário está tentando autenticar, ele poderá usar esse parâmetro para fornecer uma dica para o servidor de autenticação do Google. O servidor usa a dica para simplificar o fluxo de login preenchendo o campo de e-mail no formulário de login ou selecionando a sessão de login múltiplo adequada. Defina o valor do parâmetro como um endereço de e-mail ou identificador |
Exemplos de URLs de autorização
As guias abaixo mostram exemplos de URLs de autorização para as diferentes opções de URI de redirecionamento.
Os URLs são idênticos, exceto pelo valor do parâmetro redirect_uri
. Os URLs
também contêm os parâmetros response_type
e client_id
obrigatórios, bem
como o parâmetro opcional state
. Cada URL contém quebras de linha e espaços para
legibilidade.
Esquema de URI personalizado
https://accounts.google.com/o/oauth2/v2/auth? scope=& response_type=code& state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken& redirect_uri=com.example.app%3A/oauth2redirect& client_id=client_id
Endereço IP de loopback
https://accounts.google.com/o/oauth2/v2/auth? scope=& response_type=code& state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken& redirect_uri=http%3A//127.0.0.1%3A9004& client_id=client_id
Etapa 3: o Google solicita o consentimento do usuário
Nesta etapa, o usuário decide se quer conceder o acesso solicitado ao app. Nesta etapa, o Google exibe uma janela de consentimento que mostra o nome do seu aplicativo e os serviços da API do Google que estão solicitando permissão de acesso com as credenciais de autorização do usuário, além de um resumo dos escopos de acesso a serem concedidos. O usuário pode consentir em conceder acesso a um ou mais escopos solicitados pelo aplicativo ou recusar a solicitação.
O aplicativo não precisa fazer nada enquanto aguarda a resposta do servidor OAuth 2.0 do Google, indicando se algum acesso foi concedido. Essa resposta é explicada na etapa a seguir.
Erros
As solicitações para o endpoint de autorização do OAuth 2.0 do Google podem exibir mensagens de erro para o usuário, em vez dos fluxos de autenticação e autorização esperados. Veja abaixo os códigos de erro comuns e as sugestões de resolução.
admin_policy_enforced
A Conta do Google não autoriza um ou mais escopos solicitados devido às políticas do administrador do Google Workspace. Consulte o artigo de ajuda do administrador do Google Workspace 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 todos os escopos ou aos escopos confidenciais e restritos até que o acesso seja explicitamente concedido ao ID do cliente OAuth.
disallowed_useragent
O endpoint de autorização é exibido em um user agent incorporado não permitido pelas políticas do OAuth 2.0 do Google.
Android
Os desenvolvedores Android podem encontrar essa mensagem de erro ao abrir solicitações de autorização em
android.webkit.WebView
.
Em vez disso, os desenvolvedores precisam usar bibliotecas do Android, como o
Login do Google para Android ou o
AppAuth para Android da OpenID Foundation.
Os desenvolvedores da Web podem encontrar esse erro quando um app Android abre um link da Web geral em um user agent incorporado e um usuário navega para o endpoint de autorização do OAuth 2.0 do Google no seu site. Os desenvolvedores precisam permitir que links gerais sejam abertos no gerenciador de links padrão do sistema operacional, que inclui gerenciadores de Links do app Android ou o app de navegação padrão. A biblioteca Guias personalizadas do Android também é uma opção compatível.
iOS
Os desenvolvedores do iOS e do macOS podem encontrar esse erro ao abrir solicitações de autorização em
WKWebView
.
Em vez disso, os desenvolvedores precisam usar bibliotecas do iOS, como o
Login do Google para iOS ou o
AppAuth para iOS da OpenID Foundation.
Os desenvolvedores da Web podem encontrar esse erro quando um app iOS ou macOS abre um link da Web geral em
um user agent incorporado e um usuário navega para o endpoint de autorização do OAuth 2.0 do Google no
seu site. Os desenvolvedores precisam permitir que links gerais sejam abertos no gerenciador de links padrão do
sistema operacional, que inclui gerenciadores de
links universais
ou o app de navegação padrão. A
biblioteca SFSafariViewController
também é uma opção compatível.
org_internal
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 específica do Google Cloud. Para mais informações sobre essa opção de configuração, consulte a seção Tipo de usuário no artigo de ajuda sobre como configurar a tela de permissão OAuth.
invalid_grant
Se você estiver usando um verificador e um desafio de código, o parâmetro code_callenge
é inválido ou está ausente. Verifique se o parâmetro code_challenge
está definido corretamente.
Ao atualizar um token de acesso, ele pode ter expirado ou foi invalidado. Autentique o usuário novamente e peça o consentimento dele para receber novos tokens. Se você continuar a ver esse erro, verifique se o aplicativo foi configurado corretamente e se está usando os tokens e parâmetros corretos na solicitação. Caso contrário, a conta de usuário pode ter sido excluída ou desativada.
redirect_uri_mismatch
O redirect_uri
transmitido na solicitação de autorização não corresponde a um URI de
redirecionamento autorizado para o ID do cliente OAuth. Revise os URIs de redirecionamento autorizados em
Google API Console Credentials page.
O redirect_uri
transmitido pode ser inválido para o tipo de cliente.
O parâmetro redirect_uri
pode se referir ao fluxo OAuth fora de banda (OOB, na sigla em inglês) que
foi descontinuado e não tem mais suporte. Consulte o
guia de migração para atualizar sua
integração.
Etapa 4: lidar com a resposta do servidor OAuth 2.0
A maneira como seu aplicativo recebe a resposta de autorização depende do esquema de URI de redirecionamento usado. Seja qual for o esquema, a
resposta conterá um código de autorização (code
) ou um erro
(error
). Por exemplo, error=access_denied
indica que o usuário
recusou a solicitação.
Se o usuário conceder acesso ao seu aplicativo, será possível trocar o código de autorização por um token de acesso e um token de atualização, conforme descrito na próxima etapa.
Etapa 5: trocar o código de autorização dos tokens de atualização e acesso
Para trocar um código de autorização por um token de acesso, chame o endpoint https://oauth2.googleapis.com/token
e defina os seguintes parâmetros:
Campos | |
---|---|
client_id |
O ID do cliente recebido do API Console Credentials page. |
client_secret |
A chave secreta do cliente recebida do API Console Credentials page. |
code |
O código de autorização retornado da solicitação inicial. |
code_verifier |
O verificador de código que você criou na Etapa 1. |
grant_type |
Conforme definido na especificação do OAuth 2.0, o valor desse campo precisa ser definido como authorization_code . |
redirect_uri |
Um dos URIs de redirecionamento listados para seu projeto no API Console
Credentials page do client_id fornecido. |
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 code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& client_secret=your_client_secret& redirect_uri=http://127.0.0.1:9004& grant_type=authorization_code
O Google responde a essa solicitação retornando um objeto JSON com um token de acesso de curta duração e um token de atualização.
A resposta 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 |
O ciclo de vida restante do token de acesso em segundos. |
id_token |
Observação:essa propriedade só será retornada se sua solicitação incluir um escopo de identidade,
como openid , profile ou email . O valor é um JSON Web Token (JWT) que contém informações de identidade assinadas digitalmente sobre o usuário. |
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. Observe que os tokens de atualização são sempre retornados para aplicativos instalados. |
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 está sempre definido como Bearer . |
O snippet a seguir mostra um exemplo de resposta:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
Como chamar APIs do Google
Depois que seu aplicativo recebe um token de acesso, é possível usá-lo para fazer chamadas para 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 Bearer
de cabeçalho HTTP Authorization
. 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 as chamadas para APIs do Google, por exemplo, ao
chamar a API Drive Files.
É possível testar todas as APIs do Google e ver os escopos delas no OAuth 2.0 Playground.
Exemplos de HTTP GET
Uma chamada para o endpoint
drive.files
(a API Drive Files) usando o cabeçalho HTTP
Authorization: Bearer
pode ser semelhante a esta. Você precisa especificar seu próprio token de acesso:
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
Esta é 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, alternativamente, 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 ao 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 POST
HTTPS
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.
O client_secret não se aplica a solicitações de clientes registrados como
aplicativos Android, iOS ou Chrome.
|
grant_type |
Conforme definido na especificação do OAuth 2.0, o valor desse 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
Se o usuário não tiver revogado o acesso concedido ao aplicativo, o servidor do token retornará 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 de cliente/usuário e outro por usuário em todos os clientes. Salve tokens de atualização no armazenamento de longo prazo e continue usando-os, 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 vão parar de funcionar.
Como revogar um token
Em alguns casos, o usuário pode querer revogar o acesso dado 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 de forma programática 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 os recursos da API exigidos por um aplicativo mudaram significativamente. 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.
Leitura complementar
A prática recomendada atual do IETF OAuth 2.0 para aplicativos nativos estabelece muitas das práticas recomendadas documentadas aqui.