Descripción general
El 16 de febrero de 2022, anunciamos planes para hacer 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 de forma correcta del flujo de OAuth fuera de banda (OOB) a las alternativas admitidas.
Esta iniciativa es una medida de protección contra ataques de phishing y suplantación de identidad de apps durante las interacciones con los extremos de autorización de OAuth 2.0 de Google.
¿Qué es OOB?
OAuth fuera de banda (OOB), también conocido como la opción manual de copiar y pegar, es un flujo heredado desarrollado para admitir clientes nativos que no tienen un URI de redireccionamiento para aceptar las credenciales después de que un usuario aprueba una solicitud de consentimiento de OAuth. El flujo OOB plantea un riesgo de phishing remoto, y los clientes deben migrar a un método alternativo para protegerse contra esta vulnerabilidad.El flujo OOB dejará de estar disponible para todos los tipos de clientes, es decir, aplicaciones web, Android, iOS, Plataforma universal de Windows (UWP), apps de Chrome, TVs y dispositivos de entrada limitada, y apps para computadoras.
Fechas clave de cumplimiento
- 28 de febrero de 2022: Se bloqueó el uso nuevo de OAuth para el flujo OOB
- 5 de septiembre de 2022: Es posible que se muestre un mensaje de advertencia visible para el usuario en las solicitudes de OAuth que no cumplan con los requisitos.
- 3 de octubre de 2022: Se dejó de usar el flujo OOB para los clientes de OAuth creados antes del 28 de febrero de 2022.
- 31 de enero de 2023: Se bloquean todos los clientes existentes (incluidos los clientes exentos).
Se mostrará un mensaje de error para el usuario en las solicitudes que no cumplan con los requisitos. El mensaje les indicará a los usuarios que la app está bloqueada y, al mismo tiempo, mostrará el correo electrónico de asistencia que registraste en la pantalla de consentimiento de OAuth en la Consola de API de Google.
- Determina si te afecta.
- Si te afecta, migra a una alternativa más segura.
Cómo determinar si te afecta
Esta baja en la disponibilidad solo se aplica a las apps en producción (es decir, las apps con el estado de publicación establecido en En producción). El flujo seguirá funcionando para las apps con el estado de publicación de prueba.
Revisa tu estado de publicación en el objeto Branding pagede OAuth del objeto Google Cloud Console y continúa con el siguiente paso si usas el flujo OOB en un proyecto con el estado de publicación "En producción".
Cómo determinar si tu app usa el flujo fuera de banda
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 un valor de URI de redireccionamiento OOB.
Inspecciona el código de tu aplicación
redirect_uri
tiene alguno de los
siguientes valores:
redirect_uri=urn:ietf:wg:oauth:2.0:oob
redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
redirect_uri=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>
Inspecciona la llamada de red saliente
- Aplicación web: Inspecciona la actividad de red en Chrome
- Android: Inspecciona el tráfico de red con el Inspector de red
-
Apps de Chrome
- Navega a la página de extensiones de Chrome.
- Marca la casilla de verificación Modo de desarrollador en la esquina superior derecha de la página de extensiones.
- Selecciona la extensión que deseas supervisar.
- Haz clic en el vínculo de la página en segundo plano en la sección Inspeccionar vistas de la página de la extensión.
- Se abrirá una ventana emergente de Herramientas para desarrolladores en la que podrás supervisar el tráfico de red en la pestaña Red
- iOS: Cómo analizar el tráfico HTTP con Instruments
- Plataforma universal de Windows (UWP): Inspecciona el tráfico de red en Visual Studio
- Apps para computadoras: Usa una herramienta de captura de red disponible para el sistema operativo para el que se desarrolló la app.
redirect_uri
tiene alguno de los siguientes valores:
redirect_uri=urn:ietf:wg:oauth:2.0:oob
redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
redirect_uri=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>
Migra a una alternativa segura
Clientes para dispositivos móviles (iOS y Android)
Si determinas que tu app usa el flujo OOB con un tipo de cliente OAuth para Android o iOS, debes migrar al uso de los SDKs recomendados (Android, iOS).
El SDK facilita el acceso a las APIs de Google y controla todas las llamadas a los extremos de autorización de OAuth 2.0 de Google.
En los vínculos a la documentación que se incluyen a continuación, se proporciona información para usar los SDKs recomendados y acceder a las APIs de Google sin usar un URI de redireccionamiento fuera de banda.
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 Android de Google Identity Services recomendada.
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));
Pasa el objeto authorizationResult
al 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.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));
El objeto 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. Para ello, incluye el token de acceso en el encabezado de una solicitud de REST o gRPC (Authorization: Bearer ACCESS_TOKEN
) o usa el autorizador del captador (GTMFetcherAuthorizationProtocol
) con la
biblioteca cliente de las APIs de Google para Objective-C de REST.
Revisa la guía de acceso del cliente para obtener información sobre cómo acceder a las APIs de Google del lado del cliente. sobre cómo acceder a las APIs de Google del lado del 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 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 OOB 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 del usuario sin usar un URI de redireccionamiento fuera de banda.
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) }); }); }); };
Revisa la guía de la API de Chrome Identity para obtener más información sobre cómo autenticar usuarios y llamar a los extremos de Google con la API de Chrome Identity.
Aplicación web
Si determinas que tu app usa el flujo OOB para una aplicación web, debes migrar a una de nuestras bibliotecas cliente de las APIs de Google. Las bibliotecas cliente para diferentes lenguajes de programación se enumeran aquí.
Las bibliotecas facilitan el acceso a las APIs de Google y controlan todas las llamadas a los extremos de Google.
Acceso del servidor (sin conexión)
- Configura un servidor y define un extremo de acceso público (el URI de redireccionamiento) para recibir el código de autorización.
- Configura el URI de redireccionamiento en el Clients page de el Google Cloud Console
El siguiente fragmento de código muestra un ejemplo de NodeJS para usar la API de Google Drive y enumerar los archivos de Google Drive de un usuario en el servidor sin usar un URI de redireccionamiento fuera de banda.
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. }); } } }
Revisa la guía de la app web del servidor para acceder a las APIs de Google desde el servidor.
Acceso del cliente
El siguiente fragmento de código en JavaScript muestra un ejemplo del uso de la API de Google para acceder a los eventos del calendario del usuario en el 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(...); }
Revisa la guía de la app web del cliente para acceder a las APIs de Google desde el cliente.
Cliente para computadoras
Si determinas que tu app usa el flujo OOB en un cliente de escritorio, debes migrar al uso del
flujo de dirección IP de bucle invertido (localhost
o 127.0.0.1
).