Visão geral
Em 16 de fevereiro de 2022, anunciamos planos para tornar as interações do Google OAuth mais seguras usando fluxos mais seguros. Este guia ajuda a entender as mudanças necessárias e as etapas usadas para migrar do fluxo do OAuth fora da banda (OOB, na sigla em inglês) para alternativas compatíveis.
Esse esforço é uma medida de proteção contra ataques de phishing e de representação de apps ataques durante interações com os endpoints de autorização do OAuth 2.0 do Google.
O que é OOB?
O OAuth fora da banda (OOB), também conhecido como opção de copiar/colar manual, é um fluxo legado desenvolvido para oferecer suporte a clientes instalados que não têm um URI de redirecionamento para aceitar as credenciais depois que um usuário aprova uma solicitação de permissão do OAuth request. O fluxo OOB representa um risco de phishing remoto, e os clientes precisam migrar para um método alternativo para se proteger contra essa vulnerabilidade.O fluxo OOB está sendo descontinuado para todos os tipos de clientes, ou seja, aplicativos da Web, Android, iOS, Plataforma Universal do Windows (UWP), apps Chrome, TVs & dispositivos de entrada limitada, apps para computador.
Principais datas de conformidade
- 28 de fevereiro de 2022 : novo uso do OAuth bloqueado para o fluxo OOB
- 5 de setembro de 2022 : uma mensagem de aviso voltada ao usuário pode ser exibida para solicitações OAuth não compatíveis
- 3 de outubro de 2022 : o fluxo OOB será descontinuado para clientes OAuth criados antes de 28 de fevereiro de 2022
- 31 de janeiro de 2023 : todos os clientes atuais serão bloqueados (incluindo os isentos)
Uma mensagem de erro voltada ao usuário será exibida para solicitações não compatíveis. A mensagem informará aos usuários que o app está bloqueado ao exibir o e-mail de suporte registrado na tela de permissão OAuth no console do Google Cloud.
- Determine se você foi afetado.
- Migre para uma alternativa mais segura se você foi afetado.
Determine se você foi afetado
Essa descontinuação é aplicável apenas a apps de produção (ou seja, apps com status de publicação definido como Em produção. O fluxo vai continuar funcionando para apps com o status de publicação Teste.
Revise o status de publicação na página de marca do OAuth do console do Google Cloud e siga para a próxima etapa se estiver usando o fluxo OOB em um projeto com um status de publicação "Em produção".
Como determinar se o app está usando o fluxo OOB
Inspecione o código do app ou a chamada de rede de saída (caso o app esteja usando uma biblioteca OAuth) para determinar se a solicitação de autorização do Google OAuth que o app está fazendo está usando um valor de URI de redirecionamento OOB.
Inspecionar o código do aplicativo
redirect_uri tem algum dos
seguintes valores:
redirect_uri=urn:ietf:wg:oauth:2.0:oobredirect_uri=urn:ietf:wg:oauth:2.0:oob:autoredirect_uri=oobhttps://accounts.google.com/o/oauth2/v2/auth? response_type=code& scope=<SCOPES>& state=<STATE>& redirect_uri=urn:ietf:wg:oauth:2.0:oob& client_id=<CLIENT_ID>
Inspecionar a chamada de rede de saída
- Aplicativo da Web - inspecionar a atividade de rede no Chrome
- Android - inspecionar o tráfego de rede com o Network Inspector
-
Apps Chrome
- Acesse a página de extensões do Chrome .
- Marque a caixa de seleção Modo de desenvolvedor no canto superior direito da página de extensão.
- Selecione a extensão que você quer monitorar.
- Clique no link página de plano de fundo na Inspecionar visualizações seção da página de extensão.
- Um pop-up Ferramentas para desenvolvedores será aberto, em que você poderá monitorar o tráfego de rede na guia Rede
- iOS - Analisar o tráfego HTTP com o Instruments
- Apps para computador - use uma ferramenta de captura de rede disponível para o sistema operacional em que o app foi desenvolvido
redirect_uri tem algum dos
seguintes valores:
redirect_uri=urn:ietf:wg:oauth:2.0:oobredirect_uri=urn:ietf:wg:oauth:2.0:oob:autoredirect_uri=oobhttps://accounts.google.com/o/oauth2/v2/auth? response_type=code& scope=<SCOPES>& state=<STATE>& redirect_uri=urn:ietf:wg:oauth:2.0:oob& client_id=<CLIENT_ID>
Migrar para uma alternativa segura
Clientes para dispositivos móveis (Android / iOS)
Se você determinar que o app está usando o fluxo OOB com um tipo de cliente OAuth do Android ou iOS, migre para o uso dos SDKs recomendados (Android, iOS).
O SDK facilita o acesso às APIs do Google e processa todas as chamadas para os endpoints de autorização do OAuth 2.0 do Google.
Os links de documentação abaixo fornecem informações sobre como usar os SDKs recomendados para acessar as APIs do Google sem usar um URI de redirecionamento OOB.
Acessar as APIs do Google no Android
Acesso do lado do cliente
O exemplo a seguir mostra como acessar as APIs do Google no lado do cliente no Android usando a biblioteca recomendada dos Serviços de Identificação do Google para Android.
ListrequestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA); AuthorizationRequest authorizationRequest = AuthorizationRequest.builder().setRequestedScopes(requestedScopes).build(); Identity.getAuthorizationClient(activity) .authorize(authorizationRequest) .addOnSuccessListener( authorizationResult -> { if (authorizationResult.hasResolution()) { // Access needs to be granted by the user PendingIntent pendingIntent = authorizationResult.getPendingIntent(); try { startIntentSenderForResult(pendingIntent.getIntentSender(), REQUEST_AUTHORIZE, null, 0, 0, 0, null); } catch (IntentSender.SendIntentException e) { Log.e(TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage()); } } else { // Access already granted, continue with user action saveToDriveAppFolder(authorizationResult); } }) .addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));
Transmita o authorizationResult para o método definido para salvar o conteúdo na pasta do Google Drive do
usuário. O authorizationResult tem o
getAccessToken() método que retorna o token de acesso.
Acesso do lado do servidor (off-line)
O exemplo a seguir mostra como acessar as APIs do Google no lado do servidor no Android.ListrequestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA); AuthorizationRequest authorizationRequest = AuthorizationRequest.builder() .requestOfflineAccess(webClientId) .setRequestedScopes(requestedScopes) .build(); Identity.getAuthorizationClient(activity) .authorize(authorizationRequest) .addOnSuccessListener( authorizationResult -> { if (authorizationResult.hasResolution()) { // Access needs to be granted by the user PendingIntent pendingIntent = authorizationResult.getPendingIntent(); try { startIntentSenderForResult(pendingIntent.getIntentSender(), REQUEST_AUTHORIZE, null, 0, 0, 0, null); } catch (IntentSender.SendIntentException e) { Log.e(TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage()); } } else { String authCode = authorizationResult.getServerAuthCode(); } }) .addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));
O authorizationResult tem o
getServerAuthCode() método que retorna o código de autorização que você pode enviar ao
seu back-end para receber um token de acesso e token de atualização.
Acessar as APIs do Google em um app iOS
Acesso do lado do cliente
O exemplo abaixo mostra como acessar as APIs do Google no lado do cliente no iOS.
user.authentication.do { authentication, error in guard error == nil else { return } guard let authentication = authentication else { return } // Get the access token to attach it to a REST or gRPC request. let accessToken = authentication.accessToken // Or, get an object that conforms to GTMFetcherAuthorizationProtocol for // use with GTMAppAuth and the Google APIs client library. let authorizer = authentication.fetcherAuthorizer() }
Use o token de acesso para chamar a API, incluindo o token de acesso no
cabeçalho de uma solicitação REST ou gRPC (Authorization: Bearer ACCESS_TOKEN),
ou usando o autorizador do buscador (GTMFetcherAuthorizationProtocol) com a
biblioteca de cliente das APIs do Google para Objective-C para REST.
Consulte o guia de acesso do lado do cliente sobre como acessar as APIs do Google no lado do cliente. sobre como acessar as APIs do Google no lado do cliente.
Acesso do lado do servidor (off-line)
O exemplo abaixo mostra como acessar as APIs do Google no lado do servidor para oferecer suporte a um cliente iOS.GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
guard error == nil else { return }
guard let user = user else { return }
// request a one-time authorization code that your server exchanges for
// an access token and refresh token
let authCode = user.serverAuthCode
}Consulte o guia de acesso do lado do servidor sobre como acessar as APIs do Google do lado do servidor.
Cliente do app Chrome
Se você determinar que o app está usando o fluxo OOB no cliente do app Chrome, migre para o uso da API Chrome Identity.
O exemplo abaixo mostra como receber todos os contatos do usuário sem usar um URI de redirecionamento OOB.
window.onload = function() { document.querySelector('button').addEventListener('click', function() { // retrieve access token chrome.identity.getAuthToken({interactive: true}, function(token) { // .......... // the example below shows how to use a retrieved access token with an appropriate scope // to call the Google People API contactGroups.get endpoint fetch( 'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=API_KEY', init) .then((response) => response.json()) .then(function(data) { console.log(data) }); }); }); };
Consulte o guia da API Chrome Identity para mais informações sobre como autenticar usuários e chamar endpoints do Google com a API Chrome Identity.
App da Web
Se você determinar que o app está usando o fluxo OOB para um aplicativo da Web, migre para o uso de uma das nossas bibliotecas de cliente das APIs do Google. Consulte a lista de bibliotecas de cliente das APIs do Google para diferentes linguagens de programação.
As bibliotecas simplificam o acesso às APIs do Google e processam todas as chamadas para os endpoints do Google.
Acesso do lado do servidor (off-line)
- Configure um servidor e defina um endpoint acessível publicamente (o URI de redirecionamento) para receber o código de autorização.
- Configure o URI de redirecionamento na página "Clientes" do console do Google Cloud.
O snippet de código a seguir mostra um exemplo do NodeJS de como usar a API Google Drive para listar os arquivos do Google Drive de um usuário do lado do servidor sem usar um URI de redirecionamento OOB.
async function main() { const server = http.createServer(async function (req, res) { if (req.url.startsWith('/oauth2callback')) { let q = url.parse(req.url, true).query; if (q.error) { console.log('Error:' + q.error); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { // TODO(developer): Handle response / error. }); } } }
Consulte o guia do app da Web do lado do servidor sobre como acessar as APIs do Google do lado do servidor.
Acesso do lado do cliente
O snippet de código a seguir, em JavaScript, mostra um exemplo de como usar a API do Google para acessar os eventos de agenda do usuário no lado do cliente.
// initTokenClient() initializes a new token client with your // web app's client ID and the scope you need access to const client = google.accounts.oauth2.initTokenClient({ client_id: 'YOUR_GOOGLE_CLIENT_ID', scope: 'https://www.googleapis.com/auth/calendar.readonly', // callback function to handle the token response callback: (tokenResponse) => { if (tokenResponse && tokenResponse.access_token) { gapi.client.setApiKey('YOUR_API_KEY'); gapi.client.load('calendar', 'v3', listUpcomingEvents); } }, }); function listUpcomingEvents() { gapi.client.calendar.events.list(...); }
Consulte o guia do app da Web do lado do cliente sobre como acessar as APIs do Google do lado do cliente.
Cliente para computador
Se você determinar que o app está usando o fluxo OOB em um cliente para computador,
migre para o uso do
fluxo de endereço IP de loopback (localhost ou 127.0.0.1).