Google Play e OAuth

Di - 2 October 2012 - in

OAuth è una tecnologia per permettere ad un’applicazione di ottenere da altre applicazioni informazioni sull’utente proteggendo però l’identità dell’utente. Un esempio banale e alla portata di tutti: su Google+ è possibile cercare se sono iscritti altri amici autorizzandolo a leggere le nostre liste di amici su altri social network e sistemi di posta elettronica, senza fornire a Google nome utente e password utilizzati su network che hanno le liste.

Tale sistema, in un web nel quale i nostri dati sono sparsi su diverse applicazioni, permette un comodo accesso alle informazioni senza dover ogni volta copiare tutto.

Google Play si sta in questi giorni auto-aggiornando silenziosamente su tutti i dispositivi Android Froyo o superiori, in modo da implementare delle API OAuth che possano fornire agli sviluppatori di app la possibilità di accedere ai dati memorizzati da Google (l’email, ad esempio), previo permesso esplicito dell’utente, senza dover ogni volta farli reinserire.

È interessante notare come una caratteristica del genere venga implementata ora su tutti i telefoni anche non recenti, senza dovere, come fanno altri produttori, dover aspettare una major release.

Da parte degli sviluppatori, l’utilizzo della nuova funzionalità è molto semplice: dopo aver verificato la disponibilità del servizio tramite la funzione isGooglePlayServicesAvailable(), per poi presentare all’utente l’intent per la scelta dell’account grazie al metodo AccountPicker.newChooseAccountIntent(), avendo cura di settare l’argomento allowableAccountTypesGoogleAuthUtil.GOOGLE_ACCOUNT_TYPE, in quanto, ovviamente, è necessario che l’account in questione sia un account Google. Inoltre, l’oggetto android.accounts.Account è superfluo, basta avere l’email che lo identifica tramite il solito account.name.

A questo punto va ottenuto il token di accesso OAuth. Il token si ottiene semplicemente con il metodo GoogleAuthUtil.getToken().

Lo scope di cui si parla nella documentazione è l’identificativo dell’applicazione alla quale si vuole accedere. Ad esempio, per Google+ lo scope è oauth2:https://www.googleapis.com/auth/plus.me, e per i profili Google è https://www.googleapis.com/auth/userinfo.profile. Si possono senza problemi specificare piú scope separandoli con uno spazio e mettendo il prefisso oauth2: solo al primo. In questo modo, il token ottenuto permette l’accesso a tutte le applicazioni dei vari scope.

Il token verrà richiesto alle applicazioni alle quali si vuole accedere. Questo comporta che la risposta possa non essere immediata: se è la prima volta che viene richiesto l’accesso, l’applicazione destinataria solitamente richiede conferma all’utente. Inoltre, questioni di richieste di rete e sovraccarichi, possono rallentare il tutto.

È quindi bene evitare di lanciare il metodo nel thread della UI, o in qualunque posto in cui un’attesa indefinita possa essere deleteria.

Il comportamento del metodo è molto ben descritto nelle specifiche. Se non riesce a ritornare un token, solleva un’eccezione. I possibili motivi per il fallimento dell’operazione sono tre:

  • L’applicazione richiede interazione all’utente, ad esempio per chiedere conferma (UserRecoverableAuthException). In tal caso, si utilizza il metodo getIntent() messo a disposizione dall’eccezione e si gestisce il risultato con onActivityResult()controllando che il permesso sia stato dato.
  • Lo scope non è valido o l’account proposto non esiste nell’applicazione destinataria (GoogleAuthException). In tal caso si notifica opportunamente l’utente.
  • Errori legati a downtime dell’applicazione destinataria, o questioni di rete e sovraccarico (IOException). Anche in questo caso la via migliore è notificare opportunamente l’utente.

Ecco un semplice esempio di gestione delle eccezioni fornito da Google:

       try {
            // Se questo ritorna, il token è utilizzabile.
            String token = GoogleAuthUtil.getToken(this, mRequest.email(),
                               mRequest.scope());
            response = doGet(token, this);

        } catch (UserRecoverableAuthException userAuthEx) {
            // Questo significa che l'utente non ha ancora abilitato l'accesso
            // a questo scope, quindi va richiesta l'autorizzazione tramite l'intent fornito
            // per risolvere la cosa. Vogliamo però farlo una sola volta: richieste multiple
            // significano che l'utente non ha autorizzato.
            if (!mSecondTry) {
                startActivityForResult(userAuthEx.getIntent(), REQUEST_CODE);
                response = null;
            } else {
                response = new Response(-1, null, "Multiple approval attempts");
            }

        }  catch (IOException ioEx) {
            // Il server è probabilmente sovraccarico, si riprova se opportuno, altrimenti si lascia perdere.
            //  bad to retry instantly, so back off
            if (backoff.shouldRetry()) {
                backoff.backoff();
                response = authenticateAndGo(backoff);
            } else {
                response =
                    new Response(-1, null, "No response from authorization server.");
            }

        }  catch (GoogleAuthException fatalAuthEx)  {
            Log.d(TAG, "Fatal Authorization Exception");
            response = new Response(-1, null, "Fatal authorization exception: " +
                               fatalAuthEx.getLocalizedMessage());
        }

Per qualunque comunicazione successiva con l’applicazione, sarà necessario passare un header HTTP Authorization contenente il token. Se ad esempio il token è abcd, sarà necessario passare:

Authorization: abcd

in testa a qualunque richiesta HTTP.

In genere le applicazioni che vogliono fare uso di OAuth vanno registrate presso l’applicazione destinataria, in maniera che chi la gestisce possa revocare l’accesso a chiunque usi la vostra applicazione in caso di questioni di sicurezza. Per registrare la vostra applicazione presso i servizi di Google, è necessario andare sull’API Console.

Buon lavoro!

Via | Android Developers Blog

Leave a Reply

Lorenzo Breda Articolo scritto da

Studente di Informatica a Roma, si occupa di programmazione web sopratutto lato server, e di accessibilità del web. Utilizza e ama Debian GNU/Linux, e si interessa di fisica, fumetto, trekking e fotografia (gli ultimi due possibilmente abbinati). Collabora con Googlab da aprile 2012.

Contatta l'autore

Previous post:

Next post: