Guida alla migrazione del flusso degli indirizzi IP di loopback

Panoramica

Il 16 febbraio 2022 abbiamo annunciato l'intenzione di rendere più sicure le interazioni con Google OAuth utilizzando flussi OAuth più sicuri. Questa guida ti aiuta a comprendere le modifiche necessarie e i passaggi per eseguire correttamente la migrazione dal flusso dell'indirizzo IP di loopback alle alternative supportate.

Questo impegno è una misura di protezione contro gli attacchi di phishing e di furto d'identità delle app durante le interazioni con gli endpoint di autorizzazione OAuth 2.0 di Google.

Che cos'è il flusso dell'indirizzo IP di loopback?

Il flusso di indirizzi IP di loopback supporta l'utilizzo di un indirizzo IP di loopback o localhost come componente host dell'URI di reindirizzamento a cui vengono inviate le credenziali dopo che un utente approva una richiesta di consenso OAuth. Questo flusso è vulnerabile agli attacchi man in the middle, in cui un'app dannosa, accedendo alla stessa interfaccia di loopback su alcuni sistemi operativi, potrebbe intercettare la risposta dal server di autorizzazione all'URI di reindirizzamento specificato e ottenere l'accesso al codice di autorizzazione.

Il flusso degli indirizzi IP di loopback è in fase di ritiro per i tipi di client OAuth di iOS, Android e Chrome, ma continuerà a essere supportato nelle app desktop.

Date chiave per la conformità

  • 14 marzo 2022: ai nuovi client OAuth viene impedito di utilizzare il flusso dell'indirizzo IP di loopback
  • 1° agosto 2022: potrebbe essere visualizzato un messaggio di avviso rivolto agli utenti per le richieste OAuth non conformi
  • 31 agosto 2022: il flusso di indirizzi IP di loopback viene bloccato per i client OAuth di Android, app di Chrome e iOS creati prima del 14 marzo 2022
  • 21 ottobre 2022: tutti i client esistenti vengono bloccati (inclusi i client esenti)

Per le richieste non conformi verrà visualizzato un messaggio di errore rivolto agli utenti. Il messaggio comunicherà agli utenti che l'app è bloccata e mostrerà l'email di assistenza che hai registrato nella schermata per il consenso OAuth nella console Google Cloud.

Per completare la procedura di migrazione, devi seguire due passaggi principali:

  1. Determina se il problema ti riguarda.
  2. Se l'operazione ti riguarda, esegui la migrazione a un'alternativa supportata.

Determina se il problema ti riguarda

Esamina il tipo di ID client OAuth

Vai alla pagina Clienti della console Google Cloud e visualizza il tipo di ID client OAuth nella sezione ID client OAuth 2.0. Sarà uno dei seguenti: Applicazione web, Android, iOS, Universal Windows Platform (UWP), App di Chrome, TV e dispositivi di input limitato, App desktop.

Se il tipo di client è Android, app di Chrome o iOS e utilizzi il flusso dell'indirizzo IP di loopback, vai al passaggio successivo.

Non devi fare nulla in relazione a questa deprecazione se utilizzi il flusso dell'indirizzo IP di loopback su un client OAuth per app desktop, poiché l'utilizzo con questo tipo di client OAuth continuerà a essere supportato.

Come determinare se la tua app utilizza il flusso di indirizzi IP di loopback

Esamina il codice dell'app o la chiamata di rete in uscita (nel caso in cui l'app utilizzi una libreria OAuth) per determinare se la richiesta di autorizzazione OAuth di Google effettuata dall'app utilizza valori URI di reindirizzamento di loopback.

Esamina il codice dell'applicazione

Esamina la sezione del codice dell'applicazione in cui effettui chiamate agli endpoint di autorizzazione di Google OAuth e determina se il parametro redirect_uri ha uno dei seguenti valori:

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

Di seguito è riportato un esempio di richiesta di flusso di reindirizzamento dell'indirizzo IP di loopback:

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

Ispeziona la chiamata di rete in uscita

Il metodo per ispezionare le chiamate di rete varia a seconda del tipo di client dell'applicazione.

Durante l'ispezione delle chiamate di rete, cerca le richieste inviate agli endpoint di autorizzazione OAuth di Google e determina se il parametro redirect_uri ha uno dei seguenti valori:

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

Di seguito è riportato un esempio di richiesta di flusso di reindirizzamento dell'indirizzo IP di loopback:

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

Esegui la migrazione a un'alternativa supportata

Client mobile (Android e iOS)

Se stabilisci che la tua app utilizza il flusso dell'indirizzo IP di loopback con un tipo di client OAuth Android o iOS, devi eseguire la migrazione agli SDK consigliati (Android, iOS).

L'SDK ti aiuta ad accedere alle API di Google e gestisce tutte le chiamate agli endpoint di autorizzazione OAuth 2.0 di Google.

I seguenti link alla documentazione forniscono informazioni su come utilizzare gli SDK consigliati per accedere alle API di Google senza utilizzare un URI di reindirizzamento dell'indirizzo IP di loopback.

Accedi alle API di Google su Android

Accesso lato client

L'esempio seguente mostra come accedere alle API di Google sul lato client su Android utilizzando la libreria Android di Servizi di identità Google consigliata.

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

Passa l'oggetto authorizationResult al metodo definito per salvare i contenuti nella cartella Drive dell'utente. authorizationResult ha il metodo getAccessToken() che restituisce il token di accesso.

Accesso lato server (offline)

Il seguente esempio mostra come accedere alle API di Google lato server su 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));

authorizationResult ha il metodo getServerAuthCode() che restituisce il codice di autorizzazione che puoi inviare al tuo backend per ottenere un token di accesso e un token di aggiornamento.

Accedi alle API di Google in un'app per iOS

Accesso lato client

L'esempio seguente mostra come accedere alle API di Google sul lato client su 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()
}

Utilizza il token di accesso per chiamare l'API, includendo il token di accesso nell'intestazione di una richiesta REST o gRPC (Authorization: Bearer <var>ACCESS_TOKEN</var>) o utilizzando l'autorizzatore del recuperatore (GTMFetcherAuthorizationProtocol) con la libreria client delle API di Google per Objective-C per REST.

Consulta la guida all'accesso lato client per scoprire come accedere alle API di Google lato client.

Accesso lato server (offline)

L'esempio seguente mostra come accedere alle API di Google sul lato server per supportare un client 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
}

Consulta la guida all'accesso lato server per scoprire come accedere alle API di Google dal lato server.

Client app di Chrome

Se stabilisci che la tua app utilizza il flusso degli indirizzi IP di loopback sul client dell'app di Chrome, devi eseguire la migrazione all'utilizzo dell'API Chrome Identity.

L'esempio seguente mostra come recuperare tutti i contatti utente senza utilizzare un URI di reindirizzamento dell'indirizzo IP di 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)
    });
   });
 });
};

Consulta la guida all'API Chrome Identity per saperne di più su come accedere agli utenti autenticati e chiamare gli endpoint Google con l'API Chrome Identity.