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!
23 commenti
Trackback e pingback
Non ci sono trackback e pingback disponibili per questo articolo
Ottimo articolo! Il link per il download del codice non và …
Fatto ora funziona! Chiedo scusa :)
Ciao Paladin, abbiamo verificato il download del codice e funziona correttamente. Hai provato ad eseguire l’operazione da un altro browser?
Ciao,
io clicco sul pulsantone di facebook ma non mi apre la popup, non succede nulla.
Ciao, chiedo scusa pe rla risposta tardiva. Nella console degli sviluppatori Javascript cosa appare?
ciao io avrei un problema… dopo aver scaricato, caricato sul mio sito e creato un database mi dice sempre che è impossibile caricare gli utenti.
Io sul database non ho inserito alcuna riga… cosa devo fare?
Ciao Andrea :)
dopo aver creato il database, hai aggiunto la tabella?
Se ci fosse un errore di connessione il risultato sarebbe diverso.
Ciao Ottima guida!
sto provando ad implementare il tuo script per recuperare anche altre informazioni.
Vorrei acquisire almeno la foto del profilo, ma non riesco. Hai qualche suggerimento da darmi?
grazie
Ri ciao! ho risolto in merito alla foto del profilo (se a qualcuno dovesse servire spiego come ho fatto).
Ma ho una domanda.. vorrei il login di Facebook con la tabella utenti “classica” di login del sito.
Qualche idea in merito ai controlli utente+password da passare per il login in modo da accogliere entrambe le casistiche dato che lo script non importa la password di facebook?
puoi dire come hai fatto?
Molto interessante, e sopratutto un articolo ben strutturato!
Ciao, ottimo articolo. Io avevo già implementato il login con facebook ma in questi giorni sono cambiate un pò di cose e non funziona più. Spero che questo script mi aiuti. Come posso implementare questo script per recuperare la foto del profilo ? Daniele cosa intendi per: vorrei il login di Facebook con la tabella utenti “classica” di login del sito.??
Grazie in anticipo
Ho provato lo script, funziona (mi salva i dati nel db e accede) ma una volta che accede non va alla index e rimane la pagina bianca con il link https://miosito.com/do_login.php?p=eyJpZEZ…. Qualche consiglio?
Ciao a tutti e scusate per la lunga assenza. Se non fa il redirect prova ad attivare gli errori con error_reporting(E_ALL); ini_set(“display_errors”, “on”); e prova a vedere cosa succede :)
Ottima guida. Peccato che debba leggerla altre 3 volte per capire dove devo mettere i vari frammenti di codice.
Per favore siate più chiari su dove inserire i frammenti di codice.
Ho notato solo dopo che è tutto scaricabile… la salvezza. Grazie ancora.
Ciao. Ottima guida! Un po’ complessa, ma alla fine ci sono riuscito. Grazie.
Ho provato a far funzionare il tuo demo creando database con tabella annessa ed ovviamente settando i parametri di connessione del database.
Il popup non si apre al click sul pulsante e sulla console di javascript appare:
connect.facebook.net/en_US/sdk.js:45 FB.login() called before FB.init().
Scusami avevo sbagliato a salvare i file in un perocorso errato..ora il pop up si apre
URL bloccato: Questo reindirizzamento non è riuscito perché l’URI di reindirizzamento non è autorizzato nelle impostazioni del client OAuth dell’applicazione. Assicurati che il client e l’accesso OAuth Web siano attivi e aggiungi tutti i domini dell’applicazione come URI di reindirizzamento OAuth validi.
Vedo di provvedere a queste impostazioni..
Ciao Marco! Ho la enorme necesita di fare tutto ciò in asp-classic e javascript, ho fatto una prova e sono rustico a registrare il utente con, pero al ritorno non so come gestire il tutto… ricomincia da capo a regirttare il utente nuovamente pero si come è già presente sul database finalmente la page si ferma alla pagina register.asp
Se invece percaso il utente non acerta la email, son solori… non so come fare…
Grazie infinite in anticipo!
Ciao, bell’articolo. Però a me esce sempre l’errore “Impossibile registrare il nuovo utente”
ottimo articolo , ma per la foto?
ciao a tutti chiedo aiuto, ho installato uno script per un sito http://www.chattabu.com dove è possibile iscriversi con il logn facebook, ho creato la mia app e tutto ok, però quando vado a fare il login mi da errore:
“Warning
URL bloccato: Questo reindirizzamento non è riuscito perché l’URI di reindirizzamento non è autorizzato nelle impostazioni del client OAuth dell’applicazione. Assicurati che il client e l’accesso OAuth Web siano attivi e aggiungi tutti i domini dell’applicazione come URI di reindirizzamento OAuth validi”
non riesco a capire quale parametro url devo inserire se qualcuno sa darmi un aiuto grazie.