Come aggiungere al nostro sito web il login basato su Facebook
Sicuramente avrete già incontrato, in moltissimi siti web, la possibilità di registrarsi e di accedere utilizzando Facebook. Questo è un modo molto veloce per l’utente per accedere ad un sito web o a un servizio senza essere però costretto a inserire dati e aspettare una email di convalida. Dal momento che tutti o quasi siamo ormai sempre connessi su Facebook, si accede davvero con un click.
Quello che faremo oggi sarà proprio implementare un sistema simile che potrete utilizzare sui vostri siti web per offrire questa possibilità ai vostri visitatori.
Prerequisiti
Per questo esempio avremo bisogno di uno spazio su un server remoto raggiungibile da Facebook, provvisto di un motore database tipo MySQL e di un web server in grado di eseguire codice PHP. Questo esempio non funzionerà in locale in quanto Facebook vi obbliga, quando realizzerete l’app proxy, a specificare gli URL autorizzati a inviare delle richieste alle API del social network. Se proprio volete lavorare in locale, allora potete farlo utilizzando servizi come DynDNS.
La seconda cosa di cui abbiamo bisogno è quella di realizzare come al solito un’app su Facebook Developer che abbia come piattaforma il nostro sito web. Ho scritto qualche mese fa un articolo su come pubblicare automaticamente dei post su Facebook in cui parlavo anche di come creare un’app su Facebook Developer. L’articolo lo trovate a questo indirizzo. Dovrete aggiungere come piattaforma “Sito web” e come URL di redirect OAuth2 valido l’URL completo della pagina login.php
. Nell’immagine qui sotto vi ho riportato i parametri necessari per configurare l’autenticazione OAuth2:
Creazione del database
Immagino che quasi tutti voi abbiate esperienza su come manipolare un database MySQL, utilizzando per esempio PhpMyAdmin. Il nostro esempio avrà bisogno solamente di una tabella per gli utenti che si può creare con la seguente query:
CREATE TABLE `utenti` ( `id` INT(10) NOT NULL AUTO_INCREMENT, `password` VARCHAR(64) NOT NULL, `nome` VARCHAR(150) NOT NULL, `cognome` VARCHAR(150) NOT NULL, `email` VARCHAR(100) NOT NULL, `id_facebook` VARCHAR(64) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB AUTO_INCREMENT=4 ;
Questa tabella è identica a tantissime altre tabelle di login utilizzate in qualsiasi sito web per gestire l’autenticazione. Quello che andremo a salvare in aggiunta (anche se non è fondamentale) sarà l’ID con cui l’utente viene identificato su Facebook.
Struttura dell’esempio
Cominciamo!
Il nostro esempio si comporrà sostanzialmente di tre piccole pagine PHP:
index.php
: sarà la nostra pagina ad accesso riservato, io ho semplicemente messo una frase dentro.login.php
: sarà la pagina con il pulsante “Login with Facebook” e che invierà le richieste alle API del social network.do_login.php
: sarà la pagina PHP che materialmente accederà al databse, registrando o caricando l’utente e imposterà le variabili di sessione per completare la procedura di login.
La pagina inziale
Per prima cosa cominciamo dalla pagina più semplice di tutte, ovvero la home page del nostro esempio. Il codice è davvero molto breve:
<?php // avvio la sessione session_start(); // verifico di aver fatto il login if (!isset($_SESSION['idUtente']) || !is_numeric($_SESSION ['idUtente']) || $_ SESSION ['idUtente'] == 0) header("Location: login.php"); ?> <html> <body> <p>Se sei arrivato qui, vuol dire che hai effettuato l'accesso :)</p> </body> </html>
La prima riga carica la sessione corrente o la crea se non era ancora stata inizializzata. L’istruzione successiva invece verifica se l’utente ha effettuato l’accesso oppure no, andando a controllare se esiste la variabile idUtente
nella sessione e, se questa esiste, se è un valore numerico valido diverso da zero. Se così fosse, allora l’utente ha già eseguito la procedura e quindi potrà vedere la pagina, altrimenti deve essere reindirizzato alla pagina di login.
La pagina di login
Qui cominciamo a fare sul serio. Inizio per prima cosa dicendovi che ci sono due modi di effettuare il login con Facebook usando JavaScript:
- Il metodo che potremmo definire all-inclusive: Facebook vi offre già un pulsante preconfezionato e già cablato che vi risparmia qualche riga di codice
- Il metodo manuale, nel quale saremo noi a scrivere il codice necessario
Io, nei miei progetti, preferisco utilizzare il secondo metodo per avere più controllo sul flusso di login. Inoltre, il numero di righe di codice da scrivere è comunque limitato perciò penso che sia la soluzione migliore.
Le prime righe di codice fanno esattamente quello che abbiamo visto nella pagina iniziale, ma al contrario: se la sessione è valida e idUtente
è un numero valido, allora l’utente non deve fare il login ma deve essere reindirizzato alla pagina principale.
<?php // avvio la sessione session_start(); // verifico di aver fatto il login if (isset($_SESSION['idUtente']) && !is_numeric($_SESSION['idUtente']) && $_SESSION['idUtente'] != 0) header("Location: index.php"); ?>
Dopo questo frammento di codice, seguono i tradizionali tag html
e body
, per poi arrivare al cuore della nostra pagina.
La prima cosa è quella di inizializzare il Facebook Javascript SDK.
<script> window.fbAsyncInit = function() { FB.init({ appId : 'APP_ID', cookie : true, xfbml : true, version : 'v2.7' }); }; // Load the SDK asynchronously (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/sdk.js"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk')); </script>
Gli unici parametri importanti da andare a impostare sono il solito appId
e la versione delle API, che attualmente è la 2.7. Questo codice è assolutamente standard, non dovrete fare altro che replicarlo nei vostri progetti andando a cambiare i valori che vi ho appena citato.
La seconda parte della pagina, invece, contiene le due funzioni che utilizzeremo per effettuare il login. Ecco il codice:
<script> function loginFacebook() { FB.login(function(response) { if (response.status === 'connected') { var idUtente = response.authResponse.userID; FB.api('/me', { fields : "name, email, first_name, last_name" }, function(response) { console.log(response); dati = { idFacebook : idUtente, cognome : response.last_name, nome : response.first_name, email : response.email }; completaLoginFacebook(dati); }); } }, { scope: 'email,public_profile' } ); } function completaLoginFacebook(dati) { window.location.href = "do_login.php?p=" + btoa(JSON.stringify(dati)); } </script>
Esaminiamo insieme la funzione loginFacebook
, la quale invoca la funzione login
della classe FB. Quest’ultima apre un popup che può andare a finire in tre modi diversi.
- Se non avete effettuato l’accesso a Facebook, allora vi sarà mostrata la finestra dove potrete inserire le vostre credenziali del social network e quindi effettuare il login.
- Se avete fatto il login ma è la prima volta che usate il sito web, allora Facebook giustamente vi chiederà di autorizzare l’accesso ai vostri dati personali.
- Infine, se avevate già effettuato l’accesso e autorizzato il sito web, tutto ciò che vedrete sarà un breve flash. Il popup si richiuderà automaticamente in una breve frazione di secondo.
Come potete vedere, la funzione login accetta due parametri.
Il secondo parametro è l’insieme dei permessi che ci servono per ottenere i dati necessari, e sono i permessi che l’utente poi andrà ad autorizzare. A noi serve public_profile,
per il nome e cognome, e il permesso speciale email
per recuperare l’indirizzo di posta elettronica.
Il primo parametro invece è una callback che sarà invocata alla chiusura del popup. La risposta è un oggetto JavaScript dal quale ci ricaviamo se l’utente è connesso oppure no a Facebook e, nel caso di risposta affermativa, il token di accesso di breve periodo dell’utente.
Dentro alla callback invochiamo quindi un’altra funzione di Facebook, la famosissima funzione api
.
Il primo parametro è l’endpoint, ovvero la risorsa su cui vogliamo lavorare.
Il secondo parametro è un array che contiene i campi che vogliamo ottenere in risposta alla chiamata.
Il terzo parametro è una ulteriore callback, che verrà chiamata al termine della chiamata.
Da questo in punto in poi sta tutto alla vostra fantasia e all’architettura del vostro sistema. Io per esempio ho costruito un oggetto JavaScript che dopo passo alla pagina PHP lato server codificato in formato JSON e quindi Base64 nella querystring.
La pagina lato server
Siamo giunti alla terza e ultima parte del nostro progetto, ovvero la pagina lato server. In questa fase verifichiamo se l’utente è registrato oppure no: se non lo è, inseriamo una nuova riga all’interno della tabella degli utenti nel database. Infine, vengono settate le variabili di sessione e si viene rimandati alla pagina principale del sito web.
La prima cosa da fare è quella di verificare, come peraltro già fatto nella pagina di login, se l’utente ha già effettuato l’accesso e nel caso in cui così non fosse viene effettuato il redirect alla pagina principale.Il passo successivo è quello di avviare una connessione con il database MySQL utilizzando MySQL PDO:
Il passo successivo è quello di avviare una connessione con il database MySQL utilizzando MySQL PDO:
// avvio una connessione con il database MySQL $dbServer = "SERVER_DATABASE"; $dbUser = "UTENTE_DATABASE"; $dbPassword = "PASSWORD_DATABASE”; $dbName = "NOME_DATABASE"; $db = new mysqli("$dbServer", "$dbUser", "$dbPassword", "$dbName"); if ($db->connect_errno) { echo "Impossibile collegarsi al database"; exit(); }
Fate attenzione, come ho esplicitamente commentato, a fare l’escape sempre dei campi che andranno all’interno di una query per evitare attacchi di tipo SQL Injection. Il parametro true
di json_decode
invece serve semplicemente a decodificare l’oggetto JSON non come un oggetto PHP ma come array associativo.
A questo punto, se la query ha restituito zero righe, allora dobbiamo registrare l’utente, altrimenti prendiamo la prima riga del risultato dell’interrogazione e salviamo l’ID dell’utente:
// decodifico i dati $parametri = json_decode(base64_decode($_GET['p']), true); // tutti i parametri devono essere formattati per evitare attacchi di tipo SQL injection $email = $db->real_escape_string($parametri['email']); $cognome = $db->real_escape_string($parametri['cognome']); $nome = $db->real_escape_string($parametri['nome']); $idFacebook = $db->real_escape_string($parametri['idFacebook']); // ora verifico se l'utente è registrato oppure no $query = "SELECT * FROM utenti WHERE email = '$email' AND id_facebook = '$idFacebook'"; $resUtente = $db->query($query); if ($db->errno != 0) { echo "Impossibile caricare l’utente"; exit(); }
Abbiamo finito!
Un possibile miglioramento
Il passo successivo potrebbe essere quello di effettuare il login attraverso una chiamata AJAX, quindi nel codice della pagina lato server al posto di redirect e messaggi di errore, si dovrebbe invece stampare nella risposta un codice numerico che identifichi il risultato dell’operazione di login. Poi, nella pagina chiamante si dovrebbe verificare il valore del codice e comportarsi in modi differenti in base all’esito della procedura di login.
Conclusione
Siamo arrivati alla fine di questo articolo! Abbiamo realizzato un prototipo molto semplice di autenticazione ad un sito web utilizzando Facebook, che si presta ad essere espanso e migliorato in molti modi e che vi permetterà di implementare un meccanismo di autenticazione molto veloce all’interno dei vostri siti web. Il codice dell’articolo lo potete scaricare a questo indirizzo.
A presto!
25 commenti
Trackback e pingback
Non ci sono trackback e pingback disponibili per questo articolo