Guia de migração do fluxo de endereços IP de loopback

Visão geral

Em 16 de fevereiro de 2022, anunciamos planos para tornar as interações do Google OAuth mais seguras usando fluxos OAuth mais seguros. Este guia ajuda a entender as mudanças necessárias e as etapas para migrar do fluxo de endereço IP de loopback 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 é o fluxo de endereço IP de loopback?

O fluxo de endereço IP de loopback permite o uso de um endereço IP de loopback ou localhost como o componente de host do URI de redirecionamento para onde as credenciais são enviadas depois que um usuário aprova uma solicitação de consentimento do OAuth. Esse fluxo é vulnerável a ataques man-in-the-middle, em que um app malicioso, ao acessar a mesma interface de loopback em alguns sistemas operacionais, pode interceptar a resposta do servidor de autorização para o URI de redirecionamento fornecido e ter acesso ao código de autorização.

O fluxo de endereço IP de loopback está sendo descontinuado para os tipos de cliente OAuth do iOS, Android e Chrome, mas continuará sendo compatível com apps para computador.

Datas importantes de compliance

  • 14 de março de 2022: novos clientes OAuth impedidos de usar o fluxo de endereço IP de loopback
  • 1º de agosto de 2022: uma mensagem de aviso voltada ao usuário pode ser exibida para solicitações do OAuth que não estão em conformidade.
  • 31 de agosto de 2022: o fluxo de endereço IP de loopback será bloqueado para clientes OAuth do Android, do app do Chrome e do iOS criados antes de 14 de março de 2022.
  • 21 de outubro de 2022: 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 compatível se você for afetado.

Determinar se você será afetado

Analisar o tipo de ID do cliente OAuth

Acesse a página Clientes do console do Google Cloud e confira o tipo de ID do cliente OAuth na seção IDs do cliente OAuth 2.0. Será uma das seguintes opções: Aplicativo da Web, Android, iOS, Plataforma Universal do Windows (UWP), App do Chrome, TVs e dispositivos de entrada limitada, App para computador.

Siga para a próxima etapa se o tipo de cliente for Android, app do Chrome ou iOS e você estiver usando o fluxo de endereço IP de loopback.

Não é preciso fazer nada relacionado a essa descontinuação se você estiver usando o fluxo de endereço IP de loopback em um cliente OAuth de app para computador, já que o uso com esse tipo de cliente OAuth vai continuar sendo aceito.

Como determinar se o app está usando o fluxo de endereço IP de loopback

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 OAuth do Google que o app está fazendo usa valores de URI de redirecionamento de loopback.

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=http://127.0.0.1:<port> (por exemplo, redirect_uri=http://127.0.0.1:3000)
  • redirect_uri=http://[::1]:<port> (por exemplo, redirect_uri=http://[::1]:3000)
  • redirect_uri=http://localhost:<port> (por exemplo, redirect_uri=http://localhost:3000)

Um exemplo de solicitação de fluxo de redirecionamento de endereço IP de loopback é semelhante ao seguinte:

https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
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 cliente do 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=http://127.0.0.1:<port> (por exemplo, redirect_uri=http://127.0.0.1:3000)
  • redirect_uri=http://[::1]:<port> (por exemplo, redirect_uri=http://[::1]:3000)
  • redirect_uri=http://localhost:<port> (por exemplo, redirect_uri=http://localhost:3000)

Um exemplo de solicitação de fluxo de redirecionamento de endereço IP de loopback é semelhante ao seguinte:

https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
client_id=<CLIENT_ID>

Migrar para uma alternativa compatível

Clientes móveis (Android e iOS)

Se você determinar que seu app está usando o fluxo de endereço IP de loopback com um tipo de cliente OAuth do 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 de endereço IP de loopback.

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 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 de endereço IP de loopback no cliente do app do Chrome, migre para a API Chrome Identity.

O exemplo a seguir mostra como receber todos os contatos do usuário sem usar um URI de redirecionamento de endereço IP de loopback.

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 autenticar usuários e chamar endpoints do Google com a API Chrome Identity.