Share via


Guest Post: Integrare il login tramite Google nelle Universal Windows app

 

Questo post è stato scritto da Alessio Iafrate, Windows Developer e fondatore della community DotNetAbruzzo

 

Tutti prima o poi nelle nostre app ci siamo trovati davanti alla necessità di permettere all'utente di potersi autenticare tramite i social network più usati. Se avete la necessità di farlo tramite Facebook il modo migliore è seguire l'ottimo post scritto da Matteo Pagani su come Integrare Facebook nelle Universal Windows app che trovate QUI.

Come ben sappiamo però bisogna cercare di facilitare l'utente il più possibile e vista la grande quantità di persone che utilizza i servizi Google è giusto fornire anche il login tramite questo provider.

Purtroppo come spesso succede Google fa le cose un pochino diverse e quindi non basta cambiare le stringhe di connessione utilizzate con altri provider tipo il già citato Facebook ma bisogna seguire qualche passaggio in più.

Andiamo con ordine:

 

 

1° passo: Registrazione alle API di Google.

 

Per poter utilizzare le API dei servizi Google occorre innanzitutto recarsi all'indirizzo

https://console.developers.google.com/

e creare un nuovo progetto. Fatto ciò nella sezione APis & auth -> API sarà possibile scegliere quali API saranno utilizzate in questo progetto.

Ultimo passo sarà recarsi nella sezione APIs & auth -> Credentials e creare un nuovo Client ID

 

 

 

fatto questo avremo a disposizione tutti i dati per poter procedere.

 

2° Inserire il codice nella nostra app

 

Iniziamo con la cosa più importante, la definizione delle varie costanti che useremo.

 

 

#if !WINDOWS_PHONE_APP

public const string GoogleCallbackUrl = "urn:ietf:wg:oauth:2.0:oob";

#else

        publicconststring GoogleCallbackUrl = "http://localhost";

#endif

publicconststring GoogleClientId = "XXXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com";

publicconststring GoogleClientSecret = "YYYYYYYYYYYYYYYYYYYYYYY";

 

 

La cosa più importante, ma più difficile da trovare, è che per poter avere l'applicazione funzionante occorre utilizzare un indirizzo di callback diverso a seconda se ci troviamo in una applicazione per Windows Phone o per desktop, noi abbiamo gestito questo in modo molto elegante con la compilazione condizionale che ci mettono a disposizione le UA.

Fatto questo siamo pronti ad invocare il WebAuthenticationBroker per effettuare l'autenticazione tramite OAuth 2, in questo esempio utilizzeremo la versione per Windows Phone, ma come detto precedentemente nel link suggerito troverete tutti i dettagli per utilizzare l'autenticazione anche nelle app Windows 8

Nell'esempio seguente è stato richiesto il permesso

https://www.googleapis.com/auth/userinfo.email

che dà accesso a recuperare l'email dell'utente, naturalmente potremo inserire tutti i permessi di cui abbiamo bisogno nello stesso URL avendo l'accortezza di separarli con uno spazio bianco.

 

 

String GoogleURL = "https://accounts.google.com/o/oauth2/auth?client_id=" + Uri.EscapeDataString(Const.GoogleClientId) + "&redirect_uri=" + Uri.EscapeDataString(Const.GoogleCallbackUrl) + "&response_type=code&scope=" + Uri.EscapeDataString("https://www.googleapis.com/auth/userinfo.email");

System.Uri StartUri = newUri(GoogleURL);

System.Uri EndUri = newUri(Const.GoogleCallbackUrl);

WebAuthenticationBroker.AuthenticateAndContinue(StartUri, EndUri, null, WebAuthenticationOptions.None);

 

 

Una volta effettuata l'autenticazione verremo rimandati al nostro metodo ContinueWebAuthentication dove poter gestire l'avvenuta autenticazione.

 

 

publicasyncvoid ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args)

{

    WebAuthenticationResult result = args.WebAuthenticationResult;

    if (result.ResponseStatus == WebAuthenticationStatus.Success)

    {

        //Estraggo il parametro code ed ottengo il vero token

        Uri uri = newUri(result.ResponseData.ToString());

        WwwFormUrlDecoder decoder = new WwwFormUrlDecoder(uri.Query);

  TokenResponse tr = await Utility.GetGoogleToken(decoder.GetFirstValueByName("code"));

    }

}

 

 

Andando ad analizzare il valore della variabile result.ResponseData ci troveremo davanti ad una stringa di questo tipo

 

 

http://localhost/?code=4/mpoxyWVYn_E0MbfBVuOjF99TrwFUx7DFcdabClbd1Sk.kqeNhfgjU04cyjz_MlCJoi0M4ylkjQI

 

 

A questo punto a differenza di quanto avviene con Facebook o simili dobbiamo eseguire un ulteriore passo, poiché quello ritornato non è il vero token da poter utilizzare per le successive richieste, ma un token da passare alla pagina https://accounts.google.com/o/oauth2/token che in caso di controllo positivo risponderà con un JSON simile al seguente con tutti i dati necessari.

 

 

{

  "access_token" : "ya29.TQE6noEOzeZKAt47_7Trth6jCiCs-8-EXyls-k5L7igj6hl04ghFa4PKaHPl0j5sZ5nsbtXTk8qwyw",

  "token_type" : "Bearer",

  "expires_in" : 3600,

  "refresh_token" : "1/ughE-aNXoFJc_wpCighj55ulV-tglkTdvjnlkf56SNs"

}

 

 

Procediamo quindi con la creazione di una classe in cui poter deserializzare il JSON ritornato

 

 

publicclassTokenResponse

{

    publicstring access_token { get; set; }

    publicstring token_type { get; set; }

    publicint expires_in { get; set; }

    publicstring refresh_token { get; set; }

}

 

 

e di un semplice metodo che prende in ingresso il codice ritornato precedentemente e si farà carico di ritornarci un oggetto di tipo TokenResponse popolato con tutti i dati che ci serviranno per poter gestire la nostra autenticazione.

 

 

publicstaticasync Task<TokenResponse> GetGoogleToken(string code)

{

 

    conststring TokenUrl = "https://accounts.google.com/o/oauth2/token";

 

    var body = newStringBuilder();

    body.Append("code=");

    body.Append(code);

    body.Append("&client_id=");

    body.Append(Uri.EscapeDataString(Const.GoogleClientId));

    body.Append("&client_secret=");

    body.Append(Uri.EscapeDataString(Const.GoogleClientSecret));

    body.Append("&redirect_uri=");

    body.Append(Uri.EscapeDataString(Const.GoogleCallbackUrl));

    body.Append("&grant_type=authorization_code");

 

    var client = new HttpClient();

    var request = new HttpRequestMessage(HttpMethod.Post, newUri(TokenUrl))

    {

        Content = new StringContent(body.ToString(), Encoding.UTF8, "application/x-www-form-urlencoded")

    };

    var response = await client.SendAsync(request);

    var content = await response.Content.ReadAsStringAsync();

 

    var serviceTequest = JsonConvert.DeserializeObject(content);

    return serviceTequest;

}

 

 

Seguendo questo approccio e modificando adeguatamente i permessi richiesti saremo in grado di poter richiedere l'autenticazione e ricevere il token per poter utilizzare tutte le API di tutti i servizi esposti pubblicamente da Google.

 

 

Se volete saperne di più, non esitate a contattarmi tramite il mio account Twitter @alessioiafrate oppure sul mio blog: http://www.acquariusoft.com