Molte applicazioni Android basano le proprie logiche su dati provenienti da un back-end. Molte volte si tratta di un server http che tramite file di testo xml o json eroga un servizio o dei semplici feeds. Questo server, ed i dati che esso fornisce, sono potenzialmente accessibili a qualsiasi client e non solo alla vostra applicazione.
Altri utenti “smanettoni” potrebbero creare un’app analoga, sfruttare i vostri servizi e pubblicarla. In molti casi questo fatto potrebbe essere un problema, ad esempio quando si ha a che fare con dati sensibili (banche, telco, sanità).
Tramite i servizi Google (disponibili su tutti i devices Android) è possibile creare delle app che letteralmente si autenticano – tramite un token – verso il proprio back-end. Il server andrà poi a verificare la genuinità del token (sempre tramite i servizi Google) e a servire la richiesta o rigettarla.
Il processo di generazione e verifica del token avviene in maniera totalmente trasparente per l’utente dell’app; non è necessario chiedere permessi espliciti perché non è necessario accedere a dati dell’utente.
Entriamo nel dettaglio
La prima cosa da fare è accedere alla console sviluppatori di Google. Il “trucco” sta nel creare un progetto in cui vi siano configurate le credenziali per l’app Android e per il server. Questo consente avere entrambi gli attori in un unico scope.
A questo punto creiamo un nuovo progetto. Il project id è irrilevante ai fini delle logiche implementative.
Dopo aver creato l’applicazione Google, occorre generare 2 differenti Client ID: uno per il server e uno per l’app.
Creiamo il primo di tipo “Web application” (in questo caso i campi “Authorized javascript origin” e “Authorized redirect URI” non hanno alcuna utilità e possiamo eliminarli).
Creiamo adesso un altro Client ID, stavolta di tipo “Installed application” e poi indichiamo “Android” come tipo di app.
Questo step prevede l’aggiunta di alcune informazioni proprie dell’app (per chiudere il cerchio) . In particolare serve indicare: 1- il package name; 2 – la fingerprint SHA1 del certificato con il quale si firma l’app. Dato che chi sviluppa app utilizza sempre due chiavi per firmare le app ovvero una di sviluppo (debug keystore) e una per il rilascio sullo store di Google, è possibile creare 2 client id di tipo “Installed application” e assegnarvi ad uno la firma del certificato di debug ed all’altro quella del certificato per lo store.
Per ottenere la firma della chiave vi rimando a questo post.
A questo punto avete a disposizione quello che vi occorre per implementare le logiche lato server e lato client (app).
Sull’app Android
Quello che serve è ottenere un token valido per l’app appena configurata. Per fare questo bisogna inserire tra le dipendenze del progetto Android della app, la libreria “google-play-services” disponibile nel SDK Android (<ANDROID-SDk-HOME>/extras/google/google_play_services ). In questo modo avremo a disposizione la GoogleAuthUtil che utilizzeremo per richiedere un token. I parametri da passare al metodo statico getToken sono (oltre al Context) l’utenza Google (ricavabile tramite AccountManager) e lo scope. Il parametro scope va costruito concatenando la string “audience:server:client_id:” con il Client ID per Web application creato poco fa (218935681112-u5m6oihqf04urhnadjhagvnnq2kms8jv.apps.googleusercontent.com) . Il token ottenuto ha il formato di una stringa (…piuttosto lunga) che potrà essere inviata (mi raccomando tramite https) come parametro al server e che il server potrà verificare.
Sul server
La verifica lato server implica un check sulla signature del token (le chiavi pubbliche sono disponibili e periodicamente rigenerate https://www.googleapis.com/oauth2/v1/certs) ed un check sui campi che hanno generato il token. Per questo processo sono disponibili delle librerie (per il php ad esempio https://github.com/google/google-api-php-client) che consentono facilmente di gestire il token.
Inizializzato il client con il Client ID per Web application di cui sopra
$client = new Google_Client();
$client->setClientId($web_id);
ricaviamo i dati che lo hanno prodotto dopo aver verificato la sua genuinità, catturando l’eccezione
try{
$token_data = $client->verifyIdToken($input[‘id_token’])->getAttributes();
}catch (Google_Auth_Exception $e){
//Gestisco l’errore per token non valido
}
Se il token è valido, possiamo fare una verifica ulteriore, confrontando i campi in esso contentuti; ad esempio
$token_data[‘payload’][‘azp’] == $app_id
dove $app_id è il Client ID della applicazione Android (stavolta).
Se tutto coincide alle nostre aspettative, possiamo servire la richiesta, viceversa possiamo servire un http 401 ad esempio.
enjoy
Per maggiori dettagli –> Articolo originale