home For developers


Git, GPG e la firma dei Commit

Qualsiasi hosting per repository Git, che sia GitHub, GitLab, Bitbucket o altro, richiede l'inserimento di una password o la presenza di una chiave - se si usa SSH - al momento del push di qualsiasi modifica effettuata. Ma allora perchè dovrei addirittura firmare i miei commit con una chiave PGP? Di fatto, una persona con sufficienti privilegi è in grado di modificare qualsiasi commit o, addirittura, compromettere il nostro account ed effettuare modifiche a nostro nome. In questi casi la certezza assoluta - a meno che non sia il nostro PC ad essere compromesso [1] - si ha solo attraverso la firma dei commit effettuati. Se pensate che tutto ciò sia un po' da paranoici probabilmente avete ragione, ma vi consiglio di dare una lettura a questa Git Horror Story scritta da Mike Gerwitz. Detto questo vediamo ora come firmare i nostri commit di Git utilizzando gpg (o gpg2), presenti nei repository ufficiali di Debian e Ubuntu. Per chi non avesse mai utilizzato uno di questi due tool sarà necessario prima di tutto generare una nuova coppia di chiavi attraverso il comando gpg2 --gen-key. Il programma chiederà dunque di inserire il vostro nome reale, l'email a cui associare le nuove chiavi e una passphrase che verrà richiesta al momento dell'utilizzo della chiave. È importante assicurarsi che l'indirizzo email inserito sia lo stesso con cui siete iscritti al servizio online - ad esempio GitHub - in caso contrario i vostri commit non verranno considerati verificati sulla piattaforma. Una volta generate dovreste ottenere una schermata simile a quella qui sopra. Utilizziamo quindi l'ID della coppia appena generata (gli ultimi 8 caratteri), nel nostro caso ECD810FF, per esportare la chiave pubblica attraverso il comando gpg2 --armor --export ECD810FF e copiamo tutto il blocco di testo risultante, comprese le righe contententi -----BEGIN PGP PUBLIC KEY BLOCK----- e -----END PGP PUBLIC KEY BLOCK-----. Restano soltanto due passaggi per ultimare il procedimento, il caricamento della chiave sul nostro profilo GitHub e la configurazione locale di Git. Per quanto riguarda il primo passo basterà accedere a GitHub e inserire una nuova chiave GPG in Settings > SSH and GPG keys. Passiamo ora alla configurazione di Git. Ci serviremo dell'ID della chiave per specificare a Git quale utilizzare per firmare i commit attraverso il comando git config --global user.signingkey ECD810FF. Per firmare il commit sarà quindi sufficiente aggiungere il parametro -S a git commit, ad esempio git commit -S -m "Woah! A signed commit!". N.B. Nel caso in cui dovessimo ricevere un errore del tipo  gpg: saltato "ECD810FF": la chiave segreta non è disponibilegpg: signing failed: la chiave segreta non è disponibileerror: gpg non è riuscito a firmare i datifatal: scrittura dell'oggetto di commit non riuscita Sarà necessario specificare il programma per la gestione delle chiavi attraverso il comando git config --global gpg.program "gpg2" (sostituendo gpg2 con il tool utilizzato). Allo stesso modo per firmare tag e release sarà sufficiente utilizzare il comando git tag -s nometag. Chiaramente è possibile verificare le firme attraverso il parametro -v per i tag e --show-signature per i commit. git log --show-signature ci mostrerà quindi la history del repository mettendo in risalto i commit firmati. È inoltre possibile effettuare merge "controllati" attraverso il parametro --verify-signatures, vale a dire che il comando git merge --verify-signatures verrà eseguito solo se tutte le modifiche risulteranno firmate.  Infine possiamo rendere totalmente automatica la procedura per la firma di commit e tag , in modo da poterci dimenticare di aggiungere i parametri -S e -s nei comandi. Per far questo basterà aggiungere un'ulteriore configurazione a Git attraverso il comando git config --global commit.gpgsign true. [Screenshot e comandi per la guida sono stati effettuati su una repository di test raggiungibile qui] [1] In questo caso non avete altra scelta che piallare il PC e stare più attenti la prossima volta.

React JS, un'introduzione

React è una libreria Javascript per creare interfacce grafiche, anche chiamate View, tramite un sistema efficiente di componenti. Questa libreria ha avuto un enorme successo, tanto da aver creato attorno a sé un vero e proprio ecosistema di sviluppatori e aziende che lo utilizzano e rilasciano tramite NPM ulteriori moduli e componenti. La natura di React è fortemente descrittiva, tanto da essere stata la prima libreria a sfruttare veramente con successo le API funzionali di Javascript; i componenti React infatti sono la rappresentazione in una sorta di HTML. Per dare una definizione più precisa possiamo dire che in React V = f(S), ossia che il componente (View) varia in funzione di un certo input S che chiamiamo stato del componente. Quindi non solo lo stato determina come apparirà il componente, ma ci garantisce che in qualsiasi momento io gli passi lo stesso input otterrò lo stesso output. Nella pratica sappiamo bene che non funziona sempre così, spesso il codice javascript si appoggia a variabili globali, che possono essere modificate in altre parti di codice rendendo molto imprevedibile il risultato. Ad esempio vogliamo creare un componente che carichi una lista di articoli da un endpoint. Naturalmente quando il componente verrà mostrato sarà vuoto, quindi vogliamo che durante il caricamento mostri uno spinner e solo quando gli articoli saranno stati scaricati li mostri al lettore. In questa casistica possiamo definire due stati: caricato e non caricato, a ciascuno di essi corrisponde una visualizzazione. See the Pen Ultimi articoli L'angolo nerd by Niccolò (@nicokant) on CodePen. Il vantaggio vero e proprio di React si intuisce nel momento in cui si vogliono collegare tra loro più componenti per creare una webapp. Torniamo indietro di qualche anno, quando i framework MV* (tra cui Angular, Ember, Backbone) ebbero molto successo, tra i motivi principali c'era la tecnica del two-way data binding, che garantisce la possibilità di avere dei modelli di dati che si aggiornino automaticamente a seconda dei cambiamenti nelle view. Questo sistema è ottimo per applicazioni con poche view e pochi modelli, ma nel momento in cui se ne combinano molte tra loro il risultato è la totale perdita della prevedibilità nel flusso dei dati e il conseguente debug più complicato. React invece si presenta con un'architettura scalabile e a stati finiti, che mette al centro lo stato dei singoli blocchi. Tramite un'estensione per il browser è possibile ispezionare i componenti, il loro stato attuale e le loro proprietà. React DOM React si compone di più pacchetti, quello base è 'react' che implementa il sistema di componenti, in aggiunta, a seconda della piattaforma per cui si vuole realizzare l'app si ha a disposizione un ulteriore pacchetto, per le pagine Web si utilizza React DOM. Questo pacchetto implementa l'effettivo funzionamento della funzione di render, ossia fa da intermediario tra il componente e il DOM, dicendo come il secondo debba essere cambiato a seconda dei cambiamenti del primo. Tutto questo viene fatto nel modo più ottimizzato possibile, dal momento che le mutazioni del DOM sono operazioni costose in termini di performance, usando un algoritmo di diff-patch che apporta il minor numero di modifiche possibili al DOM. Questa funzionalità è anche nota come Virtual Dom e potete trovarla anche in altre librerie. React Native Come dicevo prima non esiste solo React DOM e il Web non è l'unica piattaforma suportata da React. Tramite React Native è possibile realizzare app Android e iOS native utilizzando comunque Javascript come linguaggio. Quanto detto per il DOM nel paragrafo precedente vale anche per iOS e Android, che avendo una base diversa dal DOM non potranno utilizzare componenti come <h1 /> oppure <a />, ma avranno a disposizione altri componenti nativi come <ScollView /> e <Text />. Cambiando piattaforma tra Web e Android/iOS è possibile riutilizzare totalmente la parte di codice relativa alla logica dell'applicazione, mentre invece i componenti vanno riscritti. we're not chasing “write once, run anywhere.” Different platforms have different looks, feels, and capabilities, and as such, we should still be developing discrete apps for each platform, but the same set of engineers should be able to build applications for whatever platform they choose, without needing to learn a fundamentally different set of technologies for each. We call this approach “learn once, write anywhere". Non stiamo inseguendo il motto "scrivi il codice una volta sola e eseguilo ovunque". Piattaforme diverse hanno un aspetto diverso, danno sensazioni diverse e hanno possibilità diverse, per questo noi vogliamo sviluppare comunque buone app per ogni piattaforma, ma uno stesso gruppo di ingegneri dovrebbe essere in grado di sviluppare applicazioni per qualsiasi piattaforma scelgano, senza aver bisogno di imparare un set fondamentalmente diverso di tecnologie per ciascuna. Chiamiamo questo approccio "impara una volta sola e scrivi codice per qualsiasi piattaforma". Chi lo usa? Bisogna sempre tenere conto di chi sviluppa il codice e di chi lo utilizza perché in alcuni casi garantisce la sopravvivenza del framework. React è sviluppato da Facebook, ma a differenza di Angular, è utilizzato in moltissime parti del social network e di altri prodotti Facebook, garantendo un ottima stabilità e l'assenza di bug catastrofici (prima di ogni release React viene testato su facebook.com). Tra i grandi nomi che utilizzano React in produzione troviamo Facebook, Whatsapp, Instagram, Airbnb, Netflix, Yahoo, Atlassian, Khan Academy, Dailymotion, eBay, IMDb, New York Times, Paypal, Periscope, Reddit, Twitter Mobile, Wordpress.com. Le app scritte con React Native sono Facebook, Instagram, Soundcloud, Tesla, Airbnb, Baidu, Vogue, Bloomberg. Se siete curiosi ne potete trovare molti altri qui.

Sitemap dinamica: cos'è e come generarla

La Sitemap non è altro che un file contenente la lista di tutte le pagine di un sito web e viene utilizzata per comunicarne l'organizzazione dei propri contenuti ai motori di ricerca. Per loro natura i crawler, software specializzati nell'analisi e raccolta di informazioni dei contenuti web, organizzano i dati in modo automatico e questo permette di poter raggiungere i contenuti online dai risultati di una ricerca sui vari Search Engine. Può capitare però che non appaia tutto ciò che vorremmo del nostro sito o che venga data una priorità maggiore a contenuti meno importanti. Occorre quindi "dare una spinta" ai motori di ricerca, fornendo loro una mappa dei contenuti e dei metadati associati, come la data dell'ultimo aggiornamento, la frequenza con cui la pagina viene modificata e l'importanza della pagina rispetto agli altri URL del sito. L'obiettivo quindi è quello di generare una Sitemap dinamica, in modo che, man mano che vengono aggiunti conenuti al sito web, questi appaiano anche nella mappa. Tale procedimento risulta necessario nel caso in cui non ci si appoggi a CMS e sistemi di gestione preesistenti, con i quali invece viene solitamente costruita in modo automatico. La Sitemap standard e accettata da tutti i motori di ricerca è tipicamente in formato XML e segue uno schema simile <?xml version="1.0" encoding="UTF-8"?> // Versione e codifica <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> // Schema <url> // Struttura dei link <loc>URL_PAGINA</loc> <lastmod>DATA_ULTIMA_MODIFICA</lastmod> // Altri parametri opzionali </url> // ... </urlset> Affinchè sia dinamica dovremo servirci di PHP per recuperare le informazioni delle pagine e degli articoli e stamparle come visto sopra, con qualche accortezza: la definizione degli header della pagina, effettuata attraverso il comando header('Content-Type: text/xml');, deve trovarsi in testa al file .php anche la definizione della versione di XML e la codifica usata, così come l'apertura del tag urlset devono trovarsi in cima alla pagina, appena sotto la funzione header Solo dopo questi tre elementi potremo scrivere il codice necessario per ottenere i link dal database  Il codice completo per la Sitemap de L'angolo nerd risulta essere quindi il seguente:   L'ultimo passaggio è quello di reindirizzare sitemap.xml al nostro file PHP, che può essere fatto attraverso una RevriteRule - vista nell'articolo precendente - dal file .htaccess in questo modo: RewriteRule ^sitemap.xml ./sitemap.php [L].

Apache e gli URL "SEO Friendly"

Per SEO, Search Engine Optimization, si intende un insieme di operazioni volte a migliorare la visibilità di un sito web sui motori di ricerca, con conseguente aumento di visualizzazioni e visite. Tra queste una delle attività più importanti è quella nota come URL Optimization, che consiste nel costruire i link delle pagine del sito in modo da risultare più leggibili e contenere qualche informazione sul contenuto della pagina stessa. Solitamente i CMS più diffusi offrono questa funzionalità out of the box. Wordpress ad esempio, come impostazione predefinita, genera link del tipo dominio/anno/mese/titolo-articolo, ma come possiamo modificarne la struttura a piacimento? E se il nostro sito non si appoggiasse ad un CMS? Ed è qui che entra in gioco Apache.   Apache HTTP Server è la piattaforma server web più diffusa, perchè in grado di operare su una grande varietà di macchine e sistemi operativi e perchè modulare, vale a dire che a seconda delle necessità è possibile caricare o meno diversi moduli della piattaforma. Tra questi ci viene in aiuto mod_rewrite, che permette di riscrivere l'url delle pagine del nostro sito. Per default questo modulo mappa un URL in un percorso sul filesystem, vale a dire che dominio/foo/bar.php indirizzerà al file bar.php contenuto nella cartella foo, ma permette anche di reindirizzare determinati URL ad altri. Questo può essere effettuato attraverso delle direttive impartite modificando il file httpd.conf (file di configurazione di Apache, solitamente non modificabile) oppure il file .htaccess presente nella root del sito web.   Tornando un attimo al SEO, l'ottimizzazione dei link deve essere effettuata tenendo conto di alcune regole base quali Evitare l'uso di query string, quali articolo.php?idarticolo=1234 Evitare link più lunghi di 250 caratteri Inserire negli indirizzi alcune informazioni sul contenuto della pagina, quali titolo, categoria o tag Nel momento in cui si progetta un sito web dinamico, i cui contenuti vengono salvati in un database, però, risulta praticamente impossibile non utilizzare le query string (quindi l'identificazione di una risorsa specifica esclusivamente attraverso parametri GET), con l'obiettivo di scrivere solo una pagina che faccia da template e che verrà popolata dal contenuto dei vari articoli. Facendo un esempio pratico, L'angolo nerd per la gestione degli articoli ha proprio una struttura di questo tipo: una pagina post.php a cui vengono passati i parametri per recuperare l'articolo corretto dal database. Come abbiamo appena visto questo non è l'approccio migliore se si tiene al proprio ranking sui motori di ricerca, quindi abbiamo utilizzato il modulo rewrite di Apache per rimappare gli URL degli articoli, in modo da avere una struttura del tipo /post/id/titolo-articolo. Per farlo è stato modificato il file .htaccess in questo modo RewriteEngine OnRewriteBase / RewriteRule ^post/([0-9]+)/[A-Za-z0-9\-\.]+/?$ post.php?id=$1 [NC,L] In particolare è necessario abilitare il rewrite attraverso il comando RewriteEngine On e poi aggiungere la regola per il mapping desiderato. La sintassi è del tipo RewriteRule pattern$ target [flags]. Il pattern inizia sempre per ^, che sta a significare la nostra webroot (www.langolonerd.it/), si conclude con $ e accetta le espressioni regolari (regex). Nel nostro caso le due regex presenti sono ([0-9]+), che sta a significare una serie di caratteri numerici non nulla, e [A-Za-z0-9\-\.]+, vale a dire una serie di caratteri alfanumerici non nulla con l'aggiunta di caratteri speciali come - e . . Il target riporta il link "reale", quello che PHP dovrà considerare per ottenere le informazioni relative a quell'articolo, a cui viene passato il parametro $1, vale a dire il "risultato" della prima espressione regolare contenuta nel pattern. Per quanto riguarda i flag abbiamo usato NC per un matching case insensitive e L per specificare al modulo Rewrite di fermarsi e non processare altre regole ogni volta che questa viene soddisfatta.    In questo modo i link agli articoli risulteranno più leggibili e più sensati, sia per gli esseri umani che per un "robot" come il Search Engine che, si spera, sarà più contento.

Android e le notifiche push con Firebase

Firebase Cloud Messaging (FCM), successore di Google Cloud Messaging GCM, è un servizio che offre una soluzione alla messaggistica istantanea multipiattaforma. Offerto da Google permette, oltre alla gestione di cloud database, piattaforme di testing, crash reporting e autenticazione, di inviare messaggi push in modo del tutto gratuito e illimitato. Vediamo quindi come utilizzare FCM per implementare le notifiche push in un sistema composto da un server PHP e un'applicazione Android. Per quanto riguarda il lato applicazione, Android Studio ci viene in aiuto integrando la piattaforma Firebase (raggiungibile da Tools > Firebase) e con pochi click potremo connettere l'app al servizio e inserire le dipendenze mancanti nel nostro progetto. Sarà infatti sufficiente specificare le dipendenze per la compilazione nei due file build.gradle, importare com.google.firebase.iid.FirebaseInstanceId nella classe in cui andremo ad utilizzarlo e inserire il file google-services.json - che possiamo reperire dalla console di Firebase - sotto app/ .   A questo punto la configurazione dell'applicazione è terminata e il token identificativo di registrazione al servizio sarà raggiungibile attraverso la chiamata al metodo FirebaseInstanceId.getInstance().getToken(). Possiamo verificare il corretto funzionamento direttamente dal pannello di Firebase, dove, nella pagina Notifications, potremo creare manualmente delle notifiche da inviare alla nostra applicazione.   Per quanto riguarda invece la configurazione lato server, utile per automatizzare l'invio delle push in determinate occorrenze, come potrebbe essere la pubblicazione di un nuovo articolo, avremo bisogno di uno script in PHP che, prese in input la chiave per le API lato server e i token delle applicazioni, invii la notifica. Innanzitutto dovremo ottenere la API key per il server, che possiamo trovare nel pannello di gestione delle API di Google. Dovrebbero esserci tre chiavi con la dicitura (auto created by Google Service) tra cui anche la Server Key.   Il codice seguente permette di generare una notifica e "spedirla" all'applicazione specificando $title e $body come titolo e contenuto della stessa: $msg = array(    'body' => $body,    'title' => $title,    'vibrate' => 1,    'sound' => 1,);$fields = array(    'registration_ids' => $registrationIds,    'notification' => $msg);$headers = array(    'Authorization: key=' . API_ACCESS_KEY,    'Content-Type: application/json');$ch = curl_init();curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );curl_setopt( $ch,CURLOPT_POST, true );curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );$result = curl_exec($ch );curl_close( $ch );return $result; Dove API_ACCESS_KEY è la Server Key e $registrationIds sarà un array di stringhe contenente i token delle applicazioni registrate. Per completare la procedura e renderla funzionante manca soltanto la gestione dei token. Per farlo sarà necessario salvare nel database del server tutti i codici delle applicazioni registrate, che avremo ottenuto attraverso il metodo getToken() citato all'inizio. Sarà quindi sufficiente, lato applicazione, chiamare questo metodo ed inviare il token al server attraverso una richiesta GET o PUSH, che provvederà poi a salvarlo nel database e recuperarlo all'occorrenza per popolare $registrationIds.

Newsletter: come rimanere sempre aggiornati

Ormai quasi tutti i siti web e blog che si rispettino lo offrono e di certo L'angolo nerd non poteva non vantare di questo servizio. Sto parlando della newsletter, un servizio che permette di inviare a tutti gli iscritti delle notifiche via email, solitamente alla pubblicazione di nuovi contenuti o con cadenze precise riportando le notizie più rilevanti (ad esempio settimanale o mensile). Attualmente questo servizio su L'angolo nerd è limitato alla notifica al momento della pubblicazione di ogni nuovo articolo ed è in costante perfezionamento, con la particolarità che è stato progettato per memorizzare meno dati personali possibili: viene infatti richesto soltanto l'inserimento dell'indirizzo email. L'iscrizione è semplicissima, basterà infatti inserire l'email nel form che potete trovare in fondo ad ogni pagina del sito (quello che vedete riportato in foto) e dal successivo articolo riceverete la notifica all'indirizzo specificato. Ogni volta che viene pubblicato un articolo viene infatti richiamata una funzione PHP che provvede a compilare il template dell'email e ad inviarla ad ogni email registrata nel database. Per ora si tratta semplicemente della classica funzione mail(): $headers = "MIME-Version: 1.0\r\n";$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";$headers .= "From: postmaster@langolonerd.it" . "\r\n" .mail($email, "Nuovo articolo disponibile | L'angolo nerd", $text, $headers);  Dove $email contiene l'indirizzo di destinazione e $text il template delle email compilato con i dati relativi al nuovo articolo. Questa funzione è però tanto semplice quanto limitata, in quanto non permette ad esempio di raccogliere statistiche o, cosa molto più importante, di garantire che ogni client email riesca a visualizzare correttamente il contenuto dell'email. Proprio per questo motivo in futuro potremmo decidere di appoggiarci a servizi come MailChimp o simili, che permettono di configurare la newsletter in modo da gestire liste di iscritti differenziate così come diversi template, nonchè l'invio di email cumulative in stile "Ecco cosa ti sei perso!" e la reportistica completa sulle newsletter inviate, ma in ogni caso verrete avvisati per qualsiasi modifica delle condizioni. Per concludere, nel caso in cui vi siate iscritti ma non voleste più ricevere alcuna email sarà sufficiente seguire il link che trovate in fondo all'email per cancellarvi definitivamente, con la consapevolezza che i vostri dati verranno realmente rimossi dal nostro database, non semplicemente "nascosti".