Guía de migración del flujo de direcciones IP de bucle invertido

Descripción general

El 16 de febrero de 2022, anunciamos planes para que las interacciones de OAuth de Google sean más seguras con flujos de OAuth más seguros. Esta guía te ayuda a comprender los cambios y los pasos necesarios para migrar correctamente del flujo de direcciones IP de bucle invertido a las alternativas admitidas.

Este esfuerzo es una medida de protección contra los ataques de phishing y de suplantación de identidad de apps durante las interacciones con los extremos de autorización de OAuth 2.0 de Google.

¿Qué es el flujo de dirección IP de bucle invertido?

El flujo de dirección IP de bucle invertido admite el uso de una dirección IP de bucle invertido o localhost como el componente de host del URI de redireccionamiento al que se envían las credenciales después de que un usuario aprueba una solicitud de consentimiento de OAuth. Este flujo es vulnerable a los ataques de intermediario, en los que una app maliciosa, que accede a la misma interfaz de bucle invertido en algunos sistemas operativos, puede interceptar la respuesta del servidor de autorización al URI de redireccionamiento determinado y obtener acceso al código de autorización.

El flujo de dirección IP de bucle invertido dejará de estar disponible para los tipos de cliente de OAuth de iOS, Android y Chrome, pero seguirá siendo compatible con las apps para computadoras.

Fechas clave para el cumplimiento

  • 14 de marzo de 2022: Se bloqueó el uso del flujo de dirección IP de bucle invertido para los clientes de OAuth nuevos.
  • 1 de agosto de 2022: Es posible que se muestre un mensaje de advertencia para el usuario en las solicitudes de OAuth que no cumplan con los requisitos.
  • 31 de agosto de 2022: Se bloquea el flujo de la dirección IP de bucle invertido para los clientes de OAuth de Android, la app de Chrome y iOS creados antes del 14 de marzo de 2022.
  • 21 de octubre de 2022: Se bloquearán todos los clientes existentes (incluidos los clientes exentos).

Se mostrará un mensaje de error para el usuario en el caso de las solicitudes que no cumplan con los requisitos. El mensaje les indicará a los usuarios que la app está bloqueada y mostrará el correo electrónico de asistencia que registraste en la pantalla de consentimiento de OAuth en la consola de Google Cloud.

Para completar el proceso de migración, debes seguir estos dos pasos principales:

  1. Determina si te afecta.
  2. Si te afecta este cambio, migra a una alternativa compatible.

Determina si te afecta

Revisa el tipo de ID de cliente de OAuth

Navega a la página Clientes de la consola de Google Cloud y consulta el tipo de ID de cliente de OAuth en la sección IDs de cliente de OAuth 2.0. Será una de las siguientes opciones: Aplicación web, Android, iOS, Plataforma universal de Windows (UWP), App de Chrome, TVs y dispositivos de entrada limitada, App para computadoras.

Continúa con el siguiente paso si tu tipo de cliente es Android, app de Chrome o iOS, y estás usando el flujo de dirección IP de bucle invertido.

No necesitas hacer nada relacionado con esta baja si usas el flujo de dirección IP de bucle invertido en un cliente de OAuth de app para computadoras, ya que se seguirá admitiendo el uso con ese tipo de cliente de OAuth.

Cómo determinar si tu app usa el flujo de dirección IP de bucle de retorno

Inspecciona el código de tu app o la llamada de red saliente (en caso de que tu app use una biblioteca de OAuth) para determinar si la solicitud de autorización de OAuth de Google que realiza tu app usa valores de URI de redireccionamiento de bucle invertido.

Inspecciona el código de tu aplicación

Revisa la sección del código de tu aplicación en la que realizas llamadas a los extremos de autorización de OAuth de Google y determina si el parámetro redirect_uri tiene alguno de los siguientes valores:

  • redirect_uri=http://127.0.0.1:<port> (por ejemplo, redirect_uri=http://127.0.0.1:3000)
  • redirect_uri=http://[::1]:<port> (por ejemplo, redirect_uri=http://[::1]:3000)
  • redirect_uri=http://localhost:<port> (por ejemplo, redirect_uri=http://localhost:3000)

A continuación, se muestra un ejemplo de solicitud de flujo de redireccionamiento de dirección IP de bucle invertido:

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

Inspecciona la llamada de red saliente

El método para inspeccionar las llamadas de red variará según el tipo de cliente de tu aplicación.

Mientras inspeccionas las llamadas de red, busca las solicitudes enviadas a los extremos de autorización de OAuth de Google y determina si el parámetro redirect_uri tiene alguno de los siguientes valores:

  • redirect_uri=http://127.0.0.1:<port> (por ejemplo, redirect_uri=http://127.0.0.1:3000)
  • redirect_uri=http://[::1]:<port> (por ejemplo, redirect_uri=http://[::1]:3000)
  • redirect_uri=http://localhost:<port> (por ejemplo, redirect_uri=http://localhost:3000)

A continuación, se muestra un ejemplo de solicitud de flujo de redireccionamiento de dirección IP de bucle invertido:

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

Migra a una alternativa compatible

Clientes móviles (Android y iOS)

Si determinas que tu app usa el flujo de dirección IP de bucle invertido con un tipo de cliente de OAuth para Android o iOS, debes migrar para usar los SDK recomendados (Android, iOS).

El SDK te ayuda a acceder a las APIs de Google y controla todas las llamadas a los extremos de autorización de OAuth 2.0 de Google.

En los siguientes vínculos a documentos, se proporciona información para usar los SDKs recomendados para acceder a las APIs de Google sin usar un URI de redireccionamiento de dirección IP de bucle invertido.

Accede a las APIs de Google en Android

Acceso del cliente

En el siguiente ejemplo, se muestra cómo acceder a las APIs de Google en el cliente en Android con la biblioteca de Google Identity Services para Android recomendada.

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));

Pasa el authorizationResult a tu método definido para guardar contenido en la carpeta de Drive del usuario. authorizationResult tiene el método getAccessToken() que devuelve el token de acceso.

Acceso del servidor (sin conexión)

En el siguiente ejemplo, se muestra cómo acceder a las APIs de Google en el servidor en 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));

El authorizationResult tiene el método getServerAuthCode() que devuelve el código de autorización que puedes enviar a tu backend para obtener un token de acceso y un token de actualización.

Accede a las APIs de Google en una app para iOS

Acceso del cliente

En el siguiente ejemplo, se muestra cómo acceder a las APIs de Google en el cliente en 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()
}

Usa el token de acceso para llamar a la API, ya sea incluyendo el token de acceso en el encabezado de una solicitud de REST o gRPC (Authorization: Bearer <var>ACCESS_TOKEN</var>) o usando el autorizador de recuperación (GTMFetcherAuthorizationProtocol) con la biblioteca cliente de las APIs de Google para Objective-C para REST.

Revisa la guía de acceso del cliente para saber cómo acceder a las APIs de Google desde el cliente.

Acceso del servidor (sin conexión)

En el siguiente ejemplo, se muestra cómo acceder a las APIs de Google en el servidor para admitir un cliente de 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
}

Revisa la guía de acceso del servidor para obtener información sobre cómo acceder a las APIs de Google desde el servidor.

Cliente de la app de Chrome

Si determinas que tu app usa el flujo de dirección IP de bucle invertido en el cliente de la app de Chrome, debes migrar al uso de la API de Chrome Identity.

En el siguiente ejemplo, se muestra cómo obtener todos los contactos de un usuario sin usar un URI de redireccionamiento de dirección IP de bucle invertido.

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)
    });
   });
 });
};

Revisa la guía de la API de Chrome Identity para obtener más información sobre cómo acceder a los usuarios autenticados y llamar a los extremos de Google con la API de Chrome Identity.