This is nerdness
Interfaccia di convergenza

Visto che ho risolto un po’ di problemi tecnici rognosi mi sto occupando dell’interfaccia.

Ho deciso che per quello di cui ho bisogno gli overlay non vanno bene. Io personalmente li rendo esteticamente orribilmente e poi ce n’è uno per ogni elemento ed è tutto confusionario. Ho quindi spostato il menu degli ordini sulla sinistra.

Mi sono anche accorto che avevo un campo description nelle schede gioco che non usavo in nessun caso, ma che può essere utile all’utente per orientarsi e così sto cercando di renderlo visualizzabile. Ho disegnato quindi una navigazione a schede nel box dei messaggi. Anche il backend per recuperare l’informazione è OK, quindi devo solo mettere mano al javascript per far andare il tutto.

Musica nelle orecchie: http://www.youtube.com/watch?v=i4laT6KDEyM 

The simple solution

Ho abbandonato questo diario un mese fa, scoraggiato, perché non riuscivo a visualizzare il nome utente FB nel mio ambiente di produzione, come invece riuscivo in ambiente di sviluppo.

Curiosamente la soluzione al problema si è rivelata estremamente semplice: mi sono limitato a passare la chiamata a graph da https a http. Evidentemente il server ha qualche restrinzione che impedice la chiamata https di essere fatta in maniera corretta.

Una volta risolto il problema tecnico (risolto… aggirato. E’ comunque una situazione fastidiosa) ho ripulito un po’ il codice e ora, correttamente, il sistema riporta il nome dell’utente nel badge.

Ora ho un mucchio di altre cose da mettere a posto.

 Musica nelle orecchie: http://www.youtube.com/watch?v=RYfccT9Tows 

500 you need

Recuperare l’immagine di profilo di Facebook è banale, se si ha l’id dell’utente, si tratta veramente solo di fabbricare correttamente la URL.

Io però volevo anche il nome utente e questo, ovviamente, ha presentato problemi.

Per ottenere i dati di un utente di Facebook è necessario invocare il Facebook Graph e leggerli da JSON che restituisce. Ovviamente questo è banale come la storia dell’avatar, visto che bisogna semplicemente fabbricare l’URL e richiamarla.

E’ però una chiamata server-side (bhe, si potrebbe fare anche client-side, a ben guardare, anzi, ora che ci penso…) che in perl ovviamente si fa passando da LWP.

Sulla mia macchina locale va tutto deliziosamente a buon fine, sul server invece ricevo un misterioso errore 500 e un ancor più misterioso messaggio “you need” senza nient’altro attaccato.

Qualcosa mi dice che passare client-side è la soluzione migliore… 

Musica nelle orecchie: http://www.youtube.com/watch?v=i82MXuIHEOY 

Logged in

Bene, login implementata.

Sarà un po’ da perlista zelota, ma c’è da dire che quando le architetture sono più e bisogna semplicemente farle girare in Dancer è tutto sempre veramente facile.

Ho fuso lo stub di login precedente con la login facebook appena completata, facendo si che il mio DB ora salvi anche lo userid facebook e colleghi quindi in modo univoco i miei utenti con quelli di Zuccobergo.

Approfittando di questo ho anche cominciato a mettere un po’ di ordine tra le navigazioni, così da avere tutte quelle bisognose di login (praticamente quelle di gioco) ben identificabili e le altre fuori, raggiungibili con facilità.

Adesso volevo dedicarmi a una pagina a cui fino a ora non ho lavorato, ovvero quella di selezione della missione che dovrebbe accogliere i nuovi utenti, ma prima penso che giocherò un po’ con il javascript SDK di FB per avere sulle mie pagine l’avatar FB degli utenti… 

Lo schema della login…

Lo schema della login…

Ti confido un segreto

Quindi l’ultima volta che ci siamo sentiti mancava il check di sicurezza.

In pratica nel cookie sono presenti due stringhe molto grosse: una rappresenta i dati dell’utente (encodati come ci siamo detti), l’altra è la stessa cosa, ma crittata con il “segreto” della app.

Ovviamente il segreto lo sappiamo solo io e Facebook. Per verificare che i dati ricevuti non siano alterati o maliziosi, quindi, mi è sufficiente crittarli e vedere se corrispondono alla loro versione, appunto, crittata.

Ma un problemino lo abbiamo, l’esempio di check dei dati è in php. In php c’è una fantastica funzione che fa così:

hash_hmac(‘sha256’, $payload, $secret, $raw = true);

e che restituisce proprio ciò che vogliamo. Valla però a tradurre in perl!

Dopo qualche tentativo, non lo nego, a spanne, ho risolto che la procedura da svolgere è:

$sig = Digest::SHA::hmac_sha256($payload, $secret);

payload è come è presente nel cookie, il secret è quello di facebook. Prima del confronto, però, necessario l’encoding!

MIME::Base64::encode_base64url($sig)

A questo punto possiamo “certificare” che i dati ricevuti sono corretti e usarli per loggare effettivamente l’utente.

Finalmente possiamo dedicarci alla parte divertente. 

 Musica nelle orecchie: http://www.youtube.com/watch?v=6rYhRqf757I 

Bare coding

Non c’è molto da scrivere. Mi sono messo a fare del perl per recuperare le informazioni dell’utente Facebook loggato e in questo ho avuto successo.

Ripercorrendo i passi dello script di cui nel post precedente, imbastendo qualche saltino tra le view Dancer, ho fatto in modo di recuperare le informazioni di cui avevo bisogno dai cookie di login FB. Devo giusto mettere a punto un piccolo check di sicurezza per chiudere il giro.

Il prossimo passo è mettere in piedi la VERA login, quella cioè che oltre a recuperare i dati li usa per creare/ottenere l’utente lato gioco e concede l’accesso alle funzionalità.
Per far questo mi sa che mi avvarrò di un diagramma di flusso.

Musica nelle orecchie:  http://www.youtube.com/watch?v=vgeV23orVx0

I’ve got to take it on the client-side

Proviamo a cambiare approccio, dopotutto la best-practice odierna è client-side. Andiamo di puro client-side anche noi.

In pratica si prende il codice HTML/JS scritto qua direttamente dalle manine degli adepti di Zuccobergo e lo si impasta in una pagina. Al click, raccontano i vati della F-blue, sarai loggato su Facebook.

Ok, ma cosa significa essere loggati su Facebook? In realtà significa avere tra i cookie del proprio sito una roba chiamata fbsr_NUMERELLO che contiene un NUMERONESTRANO.

Numerello è semplicemente la app_id dell’applicazione che fa da ponte all’autenticazione (bhe, di questo sapevamo già l’esistenza), mentre numeronestrano è un JSON contenente le informazioni dell’utente serializzato e encodato secondo il secret dell’app stessa.

Facendo dei bassi smandruppi (Facebook offre, purtroppo, l’implementazione php), quindi, è possibile, anche server side, a questo punto, riconoscere l’ID dell’utente che sta navigando sul nostro sito. In fondo non volevo molto altro… per ora almeno.

Rimane da scrivere del codice perl.

Musica nelle orecchie: http://www.youtube.com/watch?v=aU9asEUAawY

Devo capire cosa mi sfugge in questo schema.
Una cosa comunque, mi è ora chiara: il secret si usa in coppia con l’authorization code nelle chiamate successive a questo giro.

Devo capire cosa mi sfugge in questo schema.

Una cosa comunque, mi è ora chiara: il secret si usa in coppia con l’authorization code nelle chiamate successive a questo giro.

Nemici vecchi e nuovi

L’integrazione con Facebook non va. Ho provato ad applicare le più lineari azioni date da Facebook::Graph e mi sono ritrovato costantemente con un buco nell’acqua.

O meglio: il mio applicativo va su Facebook, ottiene da lui un access token, ma quando poi torna da me e cerco di usare l’access token per recuperare i miei dati utenti scopro che questo non funziona.

Per la precisione facebook debugger scrive un laconico Error validating application.

Mi son convinto che il problema poteva essere plack, che mascherava la provenienza della chiamata e magari dava l’impressione che la comunicazione non provenisse dal sito accreditato. Mi sono quindi cimentato nel trasformare l’applicazione in una banale CGI.

Bhe, c’è un motivo se la maggior parte del pianeta ha mollato Apache a sé stesso e si è gettato sui server dedicati. Apache non ha problemi di per sé, ma la verità è che la libertà che dà, per esempio, proprio plack, è qualcosa di superiore.

Innanzitutto con plack non avete problemi di permessi. Quello che vi funziona come server di test vi funzionerà anche in produzione. L’utente che lancia plack può essere benissimo l’utente applicativo dedicato, non necessariamente quello di apache e visto che quell’utente può fare il bello e il cattivo tempo nelle sue directory, questo significa che non avrete problemi di permessi, mai. E sapete bene che i problemi di permessi sono il pane quotidiano quando si deployano siti.

Come se non bastasse salta fuori un nuovo baco di documentazione.

Dancer::Deployment dice che, per dare a Dancer l’indicazione di quale environment usare nel caso di CGI si può benissimo fare un setenv nella configurazione Apache scrivendo una certa variabile d’ambiente. Questo è CLAMOROSAMENTE FALSO. L’unico modo per stabilire l’ambiente che verrà usato è entrare nel dispatcher.cgi e modificarlo lì.

Comunque, per quanto istruttiva, l’oretta buttata per far girare il sito via CGI è stata inutile per lo scopo principale. Facebook continua a rinnegarmi…