Guia de migração do fluxo fora de banda (OOB)

Visão geral

Em 16 de fevereiro de 2022, anunciamos planos para tornar as interações do OAuth do Google mais seguras usando fluxos OAuth mais seguros. Este guia ajuda a entender as mudanças necessárias e as etapas usadas para migrar do fluxo fora de banda (OOB, na sigla em inglês) do OAuth para alternativas compatíveis.

Essa iniciativa é uma medida de proteção contra ataques de phishing e falsificação de identidade de apps durante interações com os endpoints de autorização do OAuth 2.0 do Google.

O que é OOB?

O OAuth fora de banda (OOB, na sigla em inglês), também conhecido como opção manual de copiar e colar, é 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 consentimento do OAuth. O fluxo OOB apresenta 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 aplicativos, ou seja, aplicativos da Web, Android, iOS, Plataforma Universal do Windows (UWP), apps do Chrome, TVs e dispositivos de entrada limitada, apps para computador.

Datas importantes de compliance

  • 28 de fevereiro de 2022: o novo uso do OAuth foi 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 foi descontinuado para clientes OAuth criados antes de 28 de fevereiro de 2022.
  • 31 de janeiro de 2023: todos os clientes atuais são bloqueados (incluindo os clientes isentos)

Uma mensagem de erro voltada ao usuário será exibida para solicitações que não estiverem em conformidade. A mensagem vai informar aos usuários que o app está bloqueado e mostrar o e-mail de suporte que você registrou na tela de permissão OAuth no console do Google Cloud.

Há duas etapas principais para concluir o processo de migração:

  1. Determine se você será afetado.
  2. Migre para uma alternativa mais segura se você for afetado.

Determinar se você será afetado

Essa descontinuação se aplica apenas a apps de produção, ou seja, apps com o status de publicação definido como Em produção. O fluxo vai continuar funcionando para apps com o status de publicação de teste.

Revise o status de publicação na página de branding do OAuth no console do Google Cloud e prossiga para a próxima etapa se estiver usando o fluxo OOB em um projeto com o 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 use uma biblioteca OAuth) para determinar se a solicitação de autorização do Google OAuth que o app está fazendo usa um valor de URI de redirecionamento OOB.

Inspecionar o código do aplicativo

Revise a seção do código do aplicativo em que você faz chamadas para os endpoints de autorização do OAuth do Google e determine se o parâmetro redirect_uri tem algum dos seguintes valores:

  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob

Veja um exemplo de solicitação de fluxo de redirecionamento OOB:

https://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 chamada de rede de saída

O método para inspecionar chamadas de rede varia de acordo com o tipo de aplicativo.

Ao inspecionar as chamadas de rede, procure solicitações enviadas aos endpoints de autorização do OAuth do Google e determine se o parâmetro redirect_uri tem algum dos seguintes valores:

  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob

Veja um exemplo de solicitação de fluxo de redirecionamento OOB:

https://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 móveis (Android e iOS)

Se você determinar que seu app está usando o fluxo de OOB com um tipo de aplicativo OAuth para Android ou iOS, migre para os SDKs recomendados (Android, iOS).

O SDK ajuda você a acessar as 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 a seguir 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.

List<Scopes> requestedScopes = 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 Drive do usuário. O authorizationResult tem o método getAccessToken(), 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.

List<Scopes> requestedScopes = 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 método getServerAuthCode(), que retorna o código de autorização que você pode enviar ao back-end para receber um token de acesso e um token de atualização.

Acessar as APIs do Google em um app iOS

Acesso do lado do cliente

O exemplo a seguir 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 <var>ACCESS_TOKEN</var>) ou usando o autorizador de busca (GTMFetcherAuthorizationProtocol) com a biblioteca de cliente das APIs do Google para Objective-C para REST.

Consulte o guia de acesso do lado do cliente para saber como acessar as APIs do Google no lado do cliente.

Acesso do lado do servidor (off-line)

O exemplo a seguir 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 para saber como acessar as APIs do Google pelo lado do servidor.

Cliente de apps do Chrome

Se você determinar que seu app está usando o fluxo OOB no cliente do app do Chrome, migre para a API Chrome Identity.

O exemplo a seguir mostra como acessar 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 following example 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 acessar usuários autenticados e chamar endpoints do Google com a API Chrome Identity.

App da Web

Se você determinar que seu app está usando o fluxo OOB para um aplicativo da Web, migre para uma das nossas bibliotecas de cliente da API do Google. Consulte a lista de bibliotecas de cliente de 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)

O modo de acesso do lado do servidor (off-line) exige que você faça o seguinte :

  • 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 em 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 de apps da Web do lado do servidor para saber como acessar as APIs do Google pelo lado do servidor.

Acesso do lado do cliente

O snippet de código a seguir, em JavaScript, mostra um exemplo de uso da API do Google para acessar os eventos da 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 de apps da Web do lado do cliente para saber como acessar as APIs do Google pelo lado do cliente.

Cliente para computador

Se você determinar que seu app está usando o fluxo OOB em um cliente para computador, migre para o fluxo de endereço IP de loopback (localhost ou 127.0.0.1).