Realizzazione della community del sito frieund.com

Transcript

Realizzazione della community del sito frieund.com
Università degli Studi di Urbino “Carlo Bo”
Facoltà di Scienze e Tecnologie
Corso di Laurea in Informatica Applicata
Progetto d'esame di linguaggi e applicazioni multimediali
Realizzazione della community del sito frieund.com
Anno Accademico 2008/2009
MONACCHI ANDREA - Matricola 227377
“Se in un primo momento l'idea non è assurda, allora non c'è nessuna speranza che si realizzi”.
Albert Einstein
La community di frieund.com – Linguaggi e applicazioni multimediali
Indice
1. Analisi dei requisiti..................................................................................................................p.5
1.1 definizione dei target
1.2 descrizione del problema
2. Realizzazione della base di dati di supporto.............................................................................p.8
2.1 Il modello concettuale: lo schema E/R
2.2 Il modello logico e l'implementazione
3. Implementazione dell'applicativo web.....................................................................................p.13
3.1 Realizzazione del template grafico
3.1.1 Utilizzo del template grafico
3.2 La community
3.2.1 La pagina di iscrizione
3.2.2 Il modulo di login
3.2.3 Impostazioni account
3.2.4 Gestione aspetto del proprio profilo
3.2.5 Il proprio profilo
3.2.6 Ricerca di un profilo
3.2.7 Visualizzazione di un utente
3.3 I canali di frieund.com
3.3.1 Recipes
3.3.2 Travelling
3.3.3 Wow
3.3.4 Eu! City
4. I vantaggi competitivi di frieund................................................................................................p.28
5. Appendice...................................................................................................................................p.30
5.1 Sicurezza delle applicazioni
5.2 Ajax & JSON
5.3 Il captcha
Pag. 3 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
Premessa
Siamo nel 2009, ormai da tempo portiamo nelle nostre tasche spiccioli particolari che richiamano il nome di un continente, da anni non siamo più chiusi ai nostri piccoli confini ma viviamo in un mercato comune, monete che portano i segni di anni di tensioni e di un passato non molto lontano in cui siamo stati nemici almeno una volta, un tentativo di integrazione in un avvenire sempre meno rassicurante per il genere umano che tenta la carta della collaborazione, un integrazione tra milioni di persone, multiculturale e inter­religiosa, una sfida del nuovo millennio che ai più scettici può apparire utopica ma che crea stabilità e sicurezza.
Su questo entusiasmo nasce l'idea di Frieund, un sito internet che dovrebbe farsi partecipe proprio di questa voglia di riscatto e di pubblicità della propria terra, seguendo quelle che sono le linee e i principi guida dell'integrazione europea, nel rispetto delle diversità e delle tradizioni che sono la vera ricchezza e il vero patrimonio da custodire gelosamente e costituiscono un passato e una base per il nostro futuro.
In un Europa di 27 paesi, è sempre più attuale il problema e la necessità di un confronto attivo che porti a conoscenza delle problematiche comuni e permetta l'insegnamento di certi principi nelle nuove generazioni. Per tali motivi è stato scelto come target primario l'adolescente, abituato alle nuove tecnologie, creativo e interattivo. Il sito prenderà la forma di un social network mantenendo quello che è il suo scopo di creare scambio di persone e idee.
Pag. 4 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
1. Analisi dei requisiti
In questo capitolo definiremo quali sono i nostri target e in quale modo vogliamo ottenere il raggiungimento del loro bisogno emozionale.
1.1 Definizione dei target
Target
Primario(adolescente) Secondario (universitario)
Terziario (famiglia)
Bisogno emozionale
Socializzazione, appartenenza ad un gruppo ed espressione di se stessi
Curiosità, innovazione, moda, alternatività, originalità, Passatempo, relax
esclusività
Stile del servizio
Giovanile, informale, aggregante, un po' aggressivo, ribelle
Dinamico, veloce, esclusivo, Familiare, rassicurante, alla moda, efficiente, semplice ed economico, innovativo
calmo e rilassante
età
11­25 anni
20­30 anni
30­60 anni
Livello reddito
basso
Medio basso
medio
Livello istruzione
Medio / medio basso
Alto
Medio/ medio basso
Occupazione
studente
Studente / ricercatore
Lavoratore (medio)
Frequenza uso internet alta
Medio alta
Medio bassa
Punti di accesso
Casa /scuola
Casa / scuola / wifi campus
casa
Veloc. Connessione
adsl
adsl
Pstn /adsl
Tipo computer
windows
Mac os/ linux / windows
windows
Browser
IE explorer / firefox
Safari/ firefox /IExplorer
IE explorer
Portatile (1280x800)
Fisso (1024x768)
Ricerche web
Viaggi, notizie, ricerche
Profilo demografico
Rapporto con le tecnologie
Risoluz. Monitor
Portatile/fisso 1280x800 | 1024x768
Comportamento online community
Attitudini
Interessi
Community, messaggistica
Scambi all'estero, community, Ricette, notizie su europa scambio informazioni
e integrazione, normative
Personalità
Curiosa e dinamica, creativa e informale
Ambiziosa e potenzialmente ricca per la creazione di contenuti di buon livello
Stile di vita
Divertimento e tecnologia, giovanile
Relativamente frenetico, Frenetico e impegnato, internet come passatempo, per internet come passatempo
Interessata e curiosa ma anche poco informata sulle nuove tecnologie
Pag. 5 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
Target
Primario(adolescente) Secondario (universitario)
Terziario (famiglia)
alcuni come fonte di notizie e stile di vita
Comportamento sul sito
Partecipe, dinamico, crea e scambia contenuti
Esperienza on line
Blog, social network, Ricerche web, tecnologia, mail e istant messaging informazioni accademiche
Lettore e talvolta creatore di contenuti
spettatore
Ricerche web, mail, notizie
Dai tre target si intuisce che il sito dovrà:
Rendere l'esperienza del visitatore la più facile, unica ed emotivamente coinvolgente possibile; dovrà dare una sensazione di pienezza, di rotondità di ambiente accogliente e senza spigoli per lo studente adolescente, dovrà assumere la forma di una scala per l'universitario con un inizio e una fine, un processo cioè da compiere per arrivare alla meta in maniera rapida ed efficace; infine dovrà assomigliare ad un recinto o una aiuola dove muoversi con tranquillità e serenità nel caso delle famiglie.
Pag. 6 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
1.2 Descrizione del problema
Per una maggiore intuitività elenchiamo i servizi offerti sotto forma di tabella:
Servizio / canale associato
Travelling
Hosting (scambi culturali e/o gemellaggi)
Ricette
Specialità dei paesi europei
Interesse
Target 1 e 2
Target 3
Eu!
Eu! City con la visualizzazione delle città
Storia integrazione europea
Le lingue
Le caratteristiche degli stati membri
Sondaggi e valutazione sull'interesse del sito
Interesse generale
Community
Profili degli utenti iscritti (stile Blog)
Target 1 e 2
Pannello di controllo personale
Wow
Foto documentative dei paesi europei
Interesse generale
In particolare dovremo realizzare una base di dati di supporto e archiviazione nelle sezioni:
­ Hosting per i dati relativi agli scambi culturali
­ Ricette che conterrà tutti i piatti inseriti dagli utenti
­ Eu! City per la memorizzazione delle città europee e la loro posizione sulla cartina
­ Community che visualizzerà i profili e darà modo di gestire i propri dati
­ Un archivio degli utenti iscritti e dei loro privilegi
­ Wow che conterrà tutte le informazioni relative agli scatti fotografici
Pag. 7 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
2 Realizzazione della base di dati di supporto
Per poter memorizzare i dati di supporto alle nostre applicazioni dovremo implementare una base di dati. Ne riportiamo il modello concettuale e quello logico.
2.1 Il modello concettuale: lo schema E/R
Pag. 8 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
2.2 Il modello logico e l'implementazione
Le successive fasi di ottimizzazione e semplificazione hanno modificato il nostro schema E/R
Procediamo alla traduzione nel rispettivo modello logico relazionale.
Città(nome, nazione, posx, posy) Dati_accesso(username, password, privilegio) Utente(username, nome, sesso, lingua, data_nascita, mail, nome_città, nazione) Piatto(nome, lingua, categoria, procedimento, ingredienti, nome_città, nazione, utente) Profilo(utente, messaggio_personale, intervista, foto, stile) Valutazione(ospite, data, voto, commento, proprietario, indirizzo) Abitazione(proprietario, indirizzo, costo_giorno, numero_posti, informazioni_aggiuntive) Nel processo di normalizzazione è stata verificata anche la normalità degli schemi di relazione che sono in BCFN (forma normale di Boyce Codd).
Pag. 9 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
Per riportare i passi di implementazione del modello logico relazionale presentiamo il dump del DB
--MySQL Dump
--- Host: 62.149.150.72
-- Generato il: 22 apr, 2009 at 12:02 AM
-- Versione MySQL: 5.0.68
-- Versione PHP: 5.2.9
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
/*!40101
/*!40101
/*!40101
/*!40101
SET
SET
SET
SET
@OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
@OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
@OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
NAMES utf8 */;
--- Database: `Sql180545_1`
--- ---------------------------------------------------------- Struttura della tabella `abitazione`
-CREATE TABLE IF NOT EXISTS `abitazione` (
`proprietario` varchar(30) collate utf8_bin NOT NULL,
`indirizzo` varchar(60) collate utf8_bin NOT NULL,
`foto` char(14) collate utf8_bin NOT NULL,
`costo_giorno` smallint(3) unsigned NOT NULL,
`numero_posti` tinyint(3) unsigned NOT NULL,
`informazioni_aggiuntive` smallint(4) unsigned NOT NULL,
`nome_citta` varchar(40) collate utf8_bin NOT NULL default '',
`nazione` char(3) collate utf8_bin NOT NULL,
PRIMARY KEY (`proprietario`,`indirizzo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `abitazione`
--- ---------------------------------------------------------- Struttura della tabella `citta`
-CREATE TABLE IF NOT EXISTS `citta` (
`nome` varchar(40) collate utf8_bin NOT NULL,
`nazione` char(3) collate utf8_bin NOT NULL,
`posx` smallint(4) unsigned NOT NULL,
`posy` smallint(4) unsigned NOT NULL,
PRIMARY KEY (`nome`,`nazione`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
Pag. 10 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
--- Dump dei dati per la tabella `citta`
--- ---------------------------------------------------------- Struttura della tabella `dati_accesso`
-CREATE TABLE IF NOT EXISTS `dati_accesso` (
`username` varchar(30) collate utf8_bin NOT NULL,
`password` char(40) collate utf8_bin NOT NULL,
`privilegio` enum('A','L','S') collate utf8_bin NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `dati_accesso`
--- ---------------------------------------------------------- Struttura della tabella `piatto`
-CREATE TABLE IF NOT EXISTS `piatto` (
`nome` varchar(40) collate utf8_bin NOT NULL,
`lingua` char(3) collate utf8_bin NOT NULL,
`categoria` enum('V','D','C','F','P') collate utf8_bin NOT NULL,
`ingredienti` text collate utf8_bin NOT NULL,
`procedimento` text collate utf8_bin NOT NULL,
`nome_citta` varchar(40) collate utf8_bin NOT NULL,
`nazione` char(3) collate utf8_bin NOT NULL,
`utente` varchar(30) collate utf8_bin NOT NULL,
PRIMARY KEY (`nome`,`lingua`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `piatto`
--- ---------------------------------------------------------- Struttura della tabella `profilo`
-CREATE TABLE IF NOT EXISTS `profilo` (
`utente` varchar(30) collate utf8_bin NOT NULL,
`messaggio_personale` text collate utf8_bin NOT NULL,
`intervista` smallint(4) unsigned NOT NULL,
`foto` tinyint(1) unsigned NOT NULL,
`stile` tinyint(2) unsigned NOT NULL,
Pag. 11 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
PRIMARY KEY (`utente`),
KEY `utente` (`utente`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `profilo`
--- ---------------------------------------------------------- Struttura della tabella `utente`
-CREATE TABLE IF NOT EXISTS `utente` (
`username` varchar(30) collate utf8_bin NOT NULL,
`nome` varchar(30) collate utf8_bin NOT NULL,
`sesso` enum('M','F') collate utf8_bin NOT NULL,
`lingua` char(3) collate utf8_bin NOT NULL,
`data_nascita` date NOT NULL,
`mail` varchar(40) collate utf8_bin NOT NULL,
`nome_citta` varchar(40) collate utf8_bin NOT NULL,
`nazione` char(3) collate utf8_bin NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `utente`
--- ---------------------------------------------------------- Struttura della tabella `valutazione`
-CREATE TABLE IF NOT EXISTS `valutazione` (
`ospite` varchar(30) collate utf8_bin NOT NULL,
`data` date NOT NULL,
`voto` tinyint(2) unsigned NOT NULL,
`commento` text collate utf8_bin NOT NULL,
`proprietario` varchar(30) collate utf8_bin NOT NULL,
`indirizzo` varchar(60) collate utf8_bin NOT NULL,
PRIMARY KEY (`ospite`,`data`),
KEY `ospite` (`ospite`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `valutazione`
--
L'uso di MyISAM è dovuto alla mancanza di InnoDB nel server MySql utilizzato. Per tale motivo i vincoli di integrità referenziale non sono stati riportati.
Pag. 12 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
3 Implementazione dell'applicativo web
È giunto il momento di realizzare la nostra applicazione di accesso e gestione dei dati.
Dopo aver costruito la nostra interfaccia grafica procederemo ai vari contenuti dinamici che fanno uso di PHP per la sua semplicità e alta compatibilità soprattutto in campo linux.
3.1 Realizzazione del template grafico
L'interfaccia del sito dovrà garantire semplicità e accessibilità, la sua staticità dovrà permettere un veloce riconoscimento delle varie funzioni. Per questo motivo è stato cercato di utilizzare colori conformi allo stile del logo e alla filosofia che tenta di rappresentare.
La posizione dei vari oggetti e la scelta delle dimensioni è stata effettuata nel rispetto della tipologia di applicativo web e nelle caratteristiche dei target e del loro bisogno emozionale che stiamo tentando di soddisfare.
Secondo la legge di Hick il tempo medio T richiesto all'utente per prendere una decisione tra quelle ugualmente probabili disponibili è dato da una legge logaritmica. Questo perchè si suppone che gli utenti suddividano l'insieme delle alternative in categorie anzichè considerarle separatamente. Ciò comporta un costo logaritmico e non lineare di tale processo.
Il numero minimo di possibilità, la presenza di una linearità negli elementi grafici che sono ripetuti quasi al monotono fanno si che l'utente sappia familiarizzare con le varie funzionalità che oltretutto sono più veloci da caricare. Il minor numero di immagini velocizza la trasmissione della pagina e l'utilizzo dei div la rende malleabile e sposta la complessità del codice al foglio di stile permettendone cosi anche una maggiore leggibilità anche in vista di future manutenzioni.
Pag. 13 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
<? include($_SERVER['DOCUMENT_ROOT'].'session.php'); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Fri.eu.nd - Your european meeting</title>
</head>
<link rel="stylesheet" type="text/css" href="http://www.frieund.com/stile.css" />
<link rel="icon" href="http://www.frieund.com/favicon.ico" />
<body>
<div id="container">
<div id="header">
<div style="float:left;">
<a href="http://www.frieund.com">
<img src="http://www.frieund.com/images/logo.png" alt="logo" border="0" />
</a>
</div>
<div style="float:right;">
<form id="form1" name="form1" method="post"
action="http://www.frieund.com/bot.php">
<div style="float:left;">
<input name="arg" type="text" class="btn1"
id="arg" />
</div>
<div style="float:left;">
<select name="for" class="btn1" id="for">
<option value="utente" selected="selected">
User
</option>
<option value="citta">
City
</option>
<option value="piatto">
Recipes
</option>
</select>
</div>
<div style="float:left;">
<input name="Submit" type="submit" class="btn1"
value="Search" />
</div>
</form>
</div>
</div>
<div id="menu">
<div id="eu">
<div class="menu_titolo">Eu!</div>
<div class="menu">
<a href="http://www.frieund.com/news.php">
News
</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/about.php">
About Europe
</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/lang.php">
The languages
</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/eumap.php">
The countries
</a>
Pag. 14 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
</div>
<div class="divuoto"></div>
</div>
</div>
<div id="canali">
<div class="menu_titolo">Channels</div>
<div class="menu">
<a href="http://www.frieund.com/city/europe.php">City</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/community/">Community</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/recipes/">Recipes</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/travelling/">Travelling</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/wow/index.php">Wow</a>
</div>
</div>
<div id="content">
</div>
CONTENUTO CENTRALE
<?php
if (isset($_POST['username']) && isset($_POST['password']) && isset($_POST['Login'])) {
// apro la connessione dal database
require_once($_SERVER['DOCUMENT_ROOT'].'conn/xyz.php');
// seleziono il database
$db = @mysql_select_db("Sql180545_1", // nome del database
$connessione) // nome della connessione
or die ("Impossibile selezionare il database.");
// eseguo la query
$result = mysql_query(sprintf("Select username, privilegio from dati_accesso where username
='%s' AND password = '%s'", mysql_real_escape_string($_POST['username']),
sha1(mysql_real_escape_string($_POST['password']))));
// controllo che esista almeno un record
if(mysql_num_rows($result) > 0)
{
// prelevo i risultati
$riga = mysql_fetch_row($result);
//dichiaro due variabili di sessione a cui assegno il valore della query
$_SESSION['username'] = $riga[0];
$_SESSION['privilegio'] = $riga[1];
}
else
{
// l'utente non è autorizzato ad entrare
$messaggio = "Access denied!!";
}
//libero la memoria utilizzata dal risultato
mysql_free_result($result);
}
else {
// chiudo la connessione con il database
mysql_close($connessione);
if(isset($_POST['Login'])) {
Pag. 15 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
}
?>
}
// non ha inserito tutti i dati
$messaggio = "You have to fill all field in the form";
<?php if(isset($_SESSION['username'])) { ?>
<div class="login">
<div class="menu_titolo">
<?php echo $_SESSION['username']; ?>
</div>
<div class="menu">
<a href="http://www.frieund.com/mypage/my.php">
My Page
</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/mypage/edit_content.php">
My Content
</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/mypage/manage.php">
Manage Page
</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/mypage/settings.php">
Account Settings
</a>
</div>
<div class="menu">
<a href="http://www.frieund.com/logout.php">
Log-out
</a>
</div>
</div>
<?php if($_SESSION['privilegio'] == 'A') { ?>
<div class="menu_admin">
<div class="menu_titolo">Administrator</div>
<div class="menu">Languages</div>
<div class="menu">Styles</div>
<div class="menu">Local</div>
</div>
<?php }
elseif($_SESSION['privilegio'] == 'L') { ?>
<div class="menu_admin">
<div class="menu_titolo">Local Administrator</div>
<div class="menu">Languages</div>
<div class="menu">Styles</div>
<div class="menu">Local</div>
</div>
<?php } ?>
<?php } else { ?>
<div class="login">
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"
name="login" id="accesso">
<div class="menu_titolo">Login</div>
<div style="font-size:10px;">User:</div>
<div align="center">
<input name="username" type="text" class="btn1" id="username"
size="15" maxlength="30" />
</div>
<div style="font-size:10px;">Password:</div>
<div align="center">
<input name="password" type="password" class="btn1"
id="password" size="15" maxlength="14" />
</div>
<div class="divuoto"></div>
Pag. 16 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
<?php if(isset($messaggio)) { echo $messaggio; }?>
<div align="center">
<input name="Login" type="submit" class="btn1" id="Login"
value="Log in" />
</div>
<?php } ?>
</html>
</body>
</div>
</div>
<div class="divuoto"></div>
<div class="menu">Remember Password</div>
<div class="menu">
<a href="http://www.frieund.com/joinus.php">
Join us for free
</a>
</div>
</form>
<div id="footer">
<div id="credits">
<div class="c1">
<a href="http://www.frieund.com/joinus.php">
Join us for free
</a>
</div>
<div class="c1">Help</div>
<div class="c1">Contact us</div>
<div class="c1">
<a href="http://www.frieund.com/filosofia.php">
Frieund philosophy
</a>
</div>
<div class="c1">Credits</div>
</div>
<div id="copyright">
&copy; Copyright 2008 - 2009 - N3T_W4RR10R - All rights reserved
</div>
</div>
come vediamo in tutte le pagine si include il file di gestione della sessione. Esso si occupa di avviarla e settare i parametri di funzionamento. In particolare non è possibile utilizzare cookie in alternativa alle sessioni.
<?php
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
session_name('permesso');
session_start();
?>
Utilizzare il template
Il template è stato spezzato in due diversi file, il primo comprende la barra superiore e il menu laterale sinistro, il secondo invece comprende il form di login e il footer.
Per utilizzare il template costruito basterà importare il file tramite la funzione php include
<?php include('temp_up.php'); ?>
<!-- contenuti centrali della pagina -->
<?php include('temp_down.php'); ?>
Pag. 17 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
3.2 La community
Il sito dovrà essere una comunità, una postazione virtuale di scambio e confronto che permetta l'interazione tra culture diverse all'interno dell'unione europea. Vediamone gli sviluppi
3.2.1 La pagina di iscrizione joinus.php
La procedura di iscrizione permette a un utente di entrare a far parte del sito, i privilegi dati saranno quelli di utente semplice e sarà possibile modificarli solo da parte dell'amministratore.
La prima fase prevede l'accettazione dei termini del trattamento dei dati.
Una volta accettate le condizioni si potrà procedere con la scelta dell'username. Con la tecnologia ajax evitiamo il reload della pagina nel susseguirsi dei check. Una volta scelto l'username tra quelli disponibili potremo procedere all'inserimento degli altri dati
Pag. 18 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
una volta inseriti tutti i dati non resta che controllare e accettarne l'inserimento
Bene siamo stati inseriti nel DB, ora possiamo usufruire dei servizi associati
Controllando la nostra mail troveremo un messaggio di benvenuto con i dati di riepilogo dell'avvenuta iscrizione.
Implementazione
I vari step della procedura di iscrizione sono regolati da una variabile passo che viene valorizzata in base al passo di provenienza e alla correttezza dei valori ogni volta che la pagina è ricaricata. Le variabili del modulo sono riprese dall'array globale POST mentre nel caso del captcha si usa una variabile di sessione in modo che il suo controllo sia più difficilmente aggirabile.
Il primo passo effettua un semplice incremento della variabile passo, nel secondo step invece in base al valore scritto invochiamo una funzione javascript che tramite un oggetto XMLHTTP request invia una richiesta asincrona di tipo POST ad una pagina php che effettua una query di selezione al DB. A questo punto in base al risultato è restituita la possibilità di avanzare o meno di passo.
Nel passo 3 si ha un semplice form html con controlli javascript sul nome, la mail e la password che avverta l'utente della loro correttezza. Tale controllo è comunque effettuato da lato server all'invio del modulo. Una volta appuratane la correttezza si avanza al passo 4 che riepiloga i dati inseriti e richiede la copia del codice di sicurezza. In caso di scorrettezza la pagina è ricaricata con un codice diverso mantenendo i vari dati, in caso affermativo si passa allo step finale che procede all'invocazione di una stored procedure sul DBMS e all'invio di una mail di conferma (formato html e se non possibile testo) all'indirizzo specificato.
Pag. 19 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
3.2.2 Il modulo di login
Visto che il template è riportato in ogni pagina è stato deciso di includere il modulo di accesso all'interno di esso. Sul menu a destra di ogni pagina potremo quindi notare il form di login con i campi text dell'username e della password.
Una volta loggati in base ai nostri privilegi (definiti nella tabella dati_accesso) visualizzeremo tipologie di menu diverse
local
admin
simple user
Il modulo invia la query alla stessa pagina che effettua una select nel DB in ricerca di un utente con l'username e la password indicati. La password è convertita tramite l'algoritmo sha­1 in una forma non leggibile a potenziali malcapitati. Una volta assicurata l'esistenza di un record con quelle caratteristiche si crea una variabile di sessione “username” che è utilizzata per l'autenticazione su tutte le pagine protette.
Allo stesso modo il logout distrugge la sessione e le variabili associate utilizzate nell'area riservata e ridireziona alla pagina principale
<?php
session_name('permesso');
session_start();
unset($_SESSION['Username']);
unset($_SESSION['Privilegio']);
$_SESSION = array();
session_destroy();
header("Location: http://www.frieund.com/index.php");
?>
Pag. 20 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
3.2.3 Impostazioni account
I dati personali e le impostazioni dell'account sono modificabili nella pagina settings che seleziona i dati della tabella utente e in caso di invio del modulo li modifica con un update.
Nel caso venga cliccato su disable account viene abilitato un div assoluto che richiede la conferma di questa delicata operazione; una volta acconsentito si verrà diretti alla pagina remove che provvederà all'invocazione della stored procedure rimuovi passando il semplice username dell'utente.
Pag. 21 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
3.2.4 Gestione dell'aspetto del proprio profilo
Ogni profilo ha come detto un proprio stile e un messaggio personale configurabili, nonché un intervista dell'utente che fornisce informazioni aggiuntive che permettono di conoscerlo meglio. Tali informazioni sono configurabili nella pagina manage che seleziona con una query tali dati e una volta premuto il bottone li sottopone di nuovo al DBMS con una update.
La foto del contatto è semplicemente inserita e la sua modifica (sostituzione) è effettuabile in una pagina separata.
Pag. 22 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
3.2.5 Il proprio profilo
Una volta effettuato l'accesso possiamo accedere direttamente alla nostra pagina che riassumerà i nostri dati e parte dei parametri configurati nel nostro profilo.
In alto il messaggio e a sinistra i dati, in basso invece le informazioni aggiuntive.
L'implementazione di tale pagina non è che una query di join tra la tabella profilo e utente e la stampa del valore memorizzato nelle variabili identificative dei campi restituiti dal recordset.
Pag. 23 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
3.2.6 Ricerca di profili
Dal canale community è possibile impostare i parametri di ricerca geografici che permettono di affinare la ricerca degli utenti iscritti alla community. Tale lista è restituita come tabella html usando la tecnologia Ajax.
Inserendo i criteri di ricerca vedremo comparire i risultati senza ricaricare la pagina
Pag. 24 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
3.2.7 Visualizzazione di un utente
Ogni utente ha una sua pagina personale, uno spazio che raccoglie alcuni dei suoi dati.
In essa possiamo distinguere tre sezioni, una top di intestazione, una laterale che stampa i dati del contatto e una centrale che permette la visualizzazione dei contenuti inseriti dal soggetto.
Ogni contatto può scegliere un foglio di stile differente che cambia la tipologia di testo e i colori associati ai diversi oggetti della pagina. É possibile inviare una mail al contatto in questione ma tale servizio è fruibile solo dagli iscritti.
La barra inferiore riporta i colori della bandiera della nazione di residenza.
Alla pagina è passato l'username con il sistema POST, tale valore una volta recuperato e filtrato da eventuali query injection parametrizza una query di join tra profilo e utente che restituisce i dati utili. Il record restituito è visualizzato nella pagina.
Nel caso dell'intervista come abbiamo notato nell'implementazione degli schemi di relazione è costituita da un campo numerico di 4 posizioni. Se convertiamo tale valore decimale in binario possiamo rappresentare fino 16 bit che ci saranno utili per questa funzionalità.
Una volta selezionato il campo, le funzioni decbin e bindec ne effettuano la conversione e i valori binari sono messi in un array che ha la stessa lunghezza dell'array delle domande che sono caricate dinamicamente da un file separato (in previsione di un sito multilingua e di espansioni future). Ciò la rende elastica e pronta a qualsiasi lista venga caricata (fino al massimo di 16 domande).
Pag. 25 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
3.3 I canali di frieund.com
Oltre alla community frieund fornisce altri servizi quali la possibilità di inserire piatti, abitazioni e fotografie.
3.3.1 Recipes
In questa sezione è possibile tramite degli appositi parametri di ricerca selezionare piatti e visualizzarne ingredienti e procedimento.
Cliccando su una entry saremo indirizzati alla pagina specifica del piatto su cui visualizzeremo tutte le informazioni associate.
3.3.2 Travelling
La sezione travelling raccoglie tutte le abitazioni disponibili per gli scambi tra utenti, anche in questo caso dei parametri di ricerca geografici ci permettono di selezionare risultati conformi alla nostra zona di interesse e visuallizzarne le informazioni associate.
Pag. 26 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
3.3.3 Wow
Wow è la sezione dedicata agli scatti fotografici, essa raccoglie e lista le foto presenti nelle cartelle delle varie tipologie di foto. Questo è possibile con un algoritmo dedicato che legge e lista sia le cartelle che i file grafici presenti. Scelta una foto è possibile segnalarla via mail ad un altro contatto o decidere di scaricarla sul proprio pc.
Successivamente si dovrà dare possibilità agli utenti di inserire le proprie foto e di posizionarle geograficamente in modo che analogamente a quanto accade per i piatti e le abitazioni siano raggiungibili dalle città.
Non entreremo nel merito di tale sezione visto che non è oggetto di relazione.
Tutti gli scatti inseriti sono proprietà del webmaster.
3.3.4 Eu! City
City è la sezione che sfrutta la tabella città del nostro database, in particolare offre servizi di ricerca di tale entità e le visualizza sulla cartina. Nel nostro caso è stato tentato l'utilizzo delle librerie GD del php che permettono la costruzione di oggetti grafici pur richiedendo molte risorse di sistema. Questa è quindi una via alternativa e provvisoria che tenta semplicemente di testarne le capacità e le metodologie di funzionamento. Per un sistema più pulito si potrebbe pensare di sfruttare le API di google maps.
Pag. 27 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
I vantaggi competitivi di frieund
Interfaccia grafica
Semplice, pulita e in grado di garantire velocità. Il logo riflette in parte lo stile del web 2.0 ma i colori e la disposizione lo rendono accessibile anche a fasce di età più alte.
Applicazioni
Il sorgente è scritto in modo da garantire le massime performance e la riduzione di codice che in ambienti di rete significa anche minor tempo di caricamento. La validità è stata provata tramite validazione del world wide web consortium (W3C) che ha appurato il rispetto della sintassi xhtml e css per il template.
Le applicazioni sono state inoltre protette da query injection, variable injection e XSS tramite dedicate funzioni di escaping e strip dei tag.
Database
Snello ed ottimizzato in modo da garantire il minor spazio occupato su disco (tramite la scelta dei tipi di dato) e velocizzato da indici costruiti sui criteri di ricerca delle nostre applicazioni.
Utilizzo delle procedure per alleggerire le nostre pagine di accesso che sono così più veloci.
Funzionalità
La procedura di iscrizione permette in 4 semplici passi di entrare a far parte della community, le informazioni inserite non sono sensibili e per tale motivo non è richiesta autorizzazione al garante della privacy per l'attività di trattamento dei dati.
Possibilità di ospitare un utente o di essere ospitati. Questo servizio è già presente sul web ma per lo più in club che richiedono una quota annuale per la fruizione. La possibilità di vedere le valutazioni (feedback) degli utenti ospitati e la possibilità di definire un vero e proprio profilo web per la nostra casa è una tipicità di frieund non presente sul mercato. A questo si aggiunge la presenza dell'intervista che sfrutta una sistema di memorizzazione innovativo per ridurre lo spazio occupato.
Ogni utente ha poi un profilo stile social network, a questi si differenzia per la possibilità di vedere in modo diretto i contenuti inseriti dall'utente senza dover ricaricare la pagina. Con un clic possiamo visualizzare le sue ricette, i suoi viaggi e le sue case; nonché avere possibilità di dialogare tramite una mail. Ogni utente può selezionare un diverso stile che da un aspetto diverso al suo profilo.
La tabella città raccoglie tutte le città e la relativa posizione sulla cartina. Tramite il motore di ricerca è possibile da qualsiasi pagina inserire una località che potremo visualizzare su una mappa e da li avere accesso a piatti, utenti e abitazioni di quella determinata località. In questo modo si incentra il concetto di ente locale e da li si parte verso gli altri canali messi a disposizione. Wow raccoglie molte foto che l'utente potrà decidere di segnalare (stile e­cards) ad un amico o di scaricare sul proprio pc. Sarà data in futuro anche la possibilità di caricarne.
Pag. 28 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
L'utilizzo dei privilegi di accesso permette la definizione di alcuni amministratori locali.
In questo modo si potrà avere la collaborazione di altri utenti per l'inserimento delle città e la traduzione nelle varie lingue europee a costo zero.
Frieund rispecchia quindi in modo pieno la filosofia del web 2.0 dove con i minimi costi sono gli utenti a creare contenuti. Una piattaforma il cui scopo primario non è l'utile ma lo scambio di idee.
Nuove funzionalità di personalizzazione (rilevanti nell'era del marketing) sono in arrivo e la flessibilità di frieund in previsione del supporto multilingua e dei continui mutamenti dei bisogni e delle mode umane lo rendono adatto ad un continuo stato di transizione.
Prezzo
Vista la filosofia con cui frieund nasce, sembra chiaro come l'utilizzo del sito sia gratuito.
Il codice è di proprietà del webmaster ma nulla vieta che porzioni di esso (che non mettano in pericolo la sicurezza delle applicazioni esistenti) siano rilasciabili sotto la licenza opensource.
Tempo
Il tempo utile alla realizzazione del sito è di 4 ore per l'interfaccia grafica e di 30 giorni per la parte di programmazione.
Alla fase implementativa è preceduta una fase di pianificazione e una di apprendimento e approfondimento dei linguaggi php, html, css, javascript e della tecnologia ajax.
Pag. 29 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
Appendice
In questa sezione trovano spazio approfondimenti su argomentazioni richiamate in fase di progettazione
Sicurezza delle applicazioni
Riportiamo in questa breve sezione alcuni dei parametri utilizzati per garantire una sicurezza dei dati memorizzati nella nostra base di dati e delle applicazioni che ne fanno uso ad eventuali accessi non autorizzati.
SQL_INJECTION (query injection)
La funzioni addslashes è in disuso mentre mysql_escape_string è stata deprecata. Al loro posto si applica la funzione mysql_real_escape_string() che permette di risolvere il problema delle query injection con l'escaping dei caratteri speciali di sql. VARIABLE INJECTION
Per evitare questo problema è stato deciso di non utilizzare variabili GET né COOKIE, il passaggio di valori avviene tramite l'array globale POST e l'autenticazione è gestita con il meccanismo delle sessioni cui è stato espressamente indicato di non usare in nessun caso cookie. Le variabili POST non sono mai recuperate dall'array $_REQUEST e su di esse sono effettuati controlli di esistenza e consistenza nonché in determinati casi il casting forzato.
XSS (Cross Site Script)
Per risolvere il problema dell'inclusione di codice malevolo è stato pensato di filtrare i dati immessi nei nostri campi.
strip_tags(stringa) si occupa di eliminare eventuali tag html e php presenti
htmlentities(stringa) converte caratteri speciali in testo html
L'utilizzo congiunto di queste due funzioni ci permettono una protezione sufficiente a tale problematica
Password
Per la protezione delle password è stato deciso l'utilizzo della funzione hash sha­1.
La lunghezza di tale campo è stata vincolata tra 8 e 14 caratteri per garantire una sicurezza minima.
Visibilità dei parametri di connessione al DBMS
Il file contenente i parametri di connessione, nonché la password in chiaro è stato memorizzato in una cartella protetta da lettura e scrittura.
Accesso al DBMS
Per la connessione al DBMS è preferibile accedere da un utente non amministratore in modo da poterne limitare i privilegi. Un utente è creabile e gestibile tramite la sintassi GRANT di MySql.
Pag. 30 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
Ajax & JSON
Riportiamo un esempio di connessione tramite l'oggetto XMLHTTP Request utilizzato per la verifica di disponibilità di un username
// Controllo della disponibilità di un username
// Andrea Monacchi
function createRequestObject() {
// se il browser è internet explorer
if(navigator.userAgent.indexOf("MSIE") != (-1)) {
// istanzio una variabile per diversificare i browser
var Classe = "MSxml2.XMLHTTP";
// se il browser è IE 5.5 usiamo una variante
if(navigator.appVersion.indexOf("MSIE 5.5") != (-1))
{
Classe = "Microsoft.XMLHTTP";
}
try { //istanzio un oggetto acriveX
XMLHTTP = new ActiveXObject(Classe);
XMLHTTP.onreadystatechange = handleResponse;
return XMLHTTP;
}
catch(e) {
document.getElementById("risultati").innerHTML = "Error!!";
}
}
// altrimenti se è un mozilla o simili
else {
try {
XMLHTTP = new XMLHttpRequest();
XMLHTTP.onload = handleResponse;
XMLHTTP.onerror = handleResponse;
return XMLHTTP;
}
catch(e) {
document.getElementById("risultati").innerHTML = "Your browser
is unable to manage this operation";
}
}
}
var http = createRequestObject();
function sndReq() {
var action = document.getElementById("usernamecheck").value;
var param = "username="+action;
//controllo che username sia almeno 5 caratteri
if(action.length < 6) {
// se la user è troppo corta lo comunico nell'area indicata
document.getElementById("risultati").innerHTML = "Username too short";
}
else {
// pulisco lo spazio nell'area
document.getElementById("risultati").innerHTML = "Searching....";
// altrimenti posso controllare se l'username è presente o meno
// devo quindi effettuare una richiesta usando il canale istanziato
// effettuo la richiesta in modo asincrono e con il metodo post
http.open('POST', 'usrex.php', true);
Pag. 31 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", param.length);
http.setRequestHeader("Connection", "close");
//Call a function when the state changes.
http.onreadystatechange = handleResponse;
// invio di dati alla pagina - in caso di richiesta asincrona è posto a NULL
http.send(param);
}
}
function handleResponse() {
if(http.readyState == 4){
var response = http.responseText;
var update = new Array();
document.getElementById("risultati").innerHTML = http.responseText;
}
}
Per lanciare la richiesta si invoca la funzione sndReq() che si occuperà del recupero dei parametri tramite l'id degli oggetti del DOM e del loro invio tramite POST alla pagina php di controllo.
Presentiamo anche la pagina che effettua la query al db
<?php
$utente = @strip_tags($_POST['username']);
// controllo successivamente l'esistenza dell'utente che in certi casi dopo il
// filtraggio potrebbe essere diventato una stringa vuota
// l'username deve essere compreso tra 5 e 30 caratteri
if(isset($utente) && (strlen($utente) < 31) && (strlen($utente) > 4)) {
// apro la connessione dal database
require_once($_SERVER['DOCUMENT_ROOT'].'conn/xyz.php');
// setto il tipo di documento restituito impostando gli header
header("Content-Type: text/plain");
// seleziono il database
$db = @mysql_select_db("Sql180545_1", // nome del database
$connessione) // nome della connessione
or die ("Impossibile selezionare il database.");
// eseguo la query
$result = @mysql_query("Select
$utente."'");
username
from
dati_accesso
where
username='".
// controllo che esista almeno un record
if(mysql_num_rows($result) > 0)
{
// se esiste un record allora lo username è gia stato usato
echo "The username ".$utente." is not available";
}
else
{
// se mysql_num_rows è zero non ci sono record e posso usare lo username
echo "The Username ".$utente." is available";
printf("</br>
<form id=\"prosegui\" name=\"prosegui\" method=\"post\" action=\"\">
</br>
Pag. 32 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
<input name=\"passo\" type=\"hidden\" id=\"passo\" value=\"3\" />
<input name=\"username\" type=\"hidden\" id=\"username\" value=\"%s\" />
<input
name=\"send\"
class=\"btn1\"
type=\"submit\"
id=\"send\"
value=\"Choose & Next\" />
</form>", $utente);
}
// chiudo la connessione con il database
mysql_close($connessione);
}
else echo "You have to insert a 5-30 chars-length username";
?>
Nel div risultati il javascript inserisce il codice html restituito dalla pagina di check utente, questo è un modo alternativo e più diretto di usare Ajax che (come dice la sigla) nella comunicazione utilizza un documento XML.
Una variante che sentiamo di proporre per future implementazioni è la tecnologia JSON (Javascript Object Notation), essa evita l'invio della pagina html ma propone il solo invio degli oggetti restituiti dal database. Ad esempio invece di restituire una pagina e il suo aspetto che caricherebbe la nostra comunicazione asincrona serializza gli oggetti sotto forma di stringa (il cui formato è riconosciuto e standardizzato a livello internazionale e per più linguaggi). Tale stringa è poi inviata al parser javascript della pagina ricevente tramite la funzione eval() ed è ora possibile ad accedere a tali oggetti come se fossero locali. Ciò risulta più elegante ed intelligente rispetto al semplice file XML.
Connessione al database
La connessione al DBMS avviene includendo il file esterno xyz (nome meno mnemonico possibile) contenente la funzione connect e le credenziali di accesso. Tale documento è stato posto nella cartella conn che ha privilegi di sola esecuzione. In tal modo si evita la copia e l'accesso al DBMS da utenti non autorizzati.
Pag. 33 di 34
La community di frieund.com – Linguaggi e applicazioni multimediali
Il captcha (completely automated public Turing test to tell computers and humans apart)
Riportiamo il codice php dello script di creazione del codice di sicurezza
<?php
// faccio partire la sessione
include($_SERVER['DOCUMENT_ROOT'].'session.php');
// genero il codice definendo il tipo di dato
header('Content-type: image/jpeg');
// definisco le dimensioni
$size_x = 150;
$size_y = 80;
// come codice segreto uso una variabile di sessione in modo che nn sia visibile all'utente
$code = $_SESSION['captcha_code'];
$space_per_char = $size_x / (strlen($code)+1);
// creo l'immagine
$img = imagecreatetruecolor($size_x, $size_y);
// alloco i colori che mi serviranno
// sfondo RGB(230,237,253)
$sfondo = imagecolorallocate($img, 230, 237, 253);
// bordo RGB(196,211,254)
$bordo = imagecolorallocate($img, 196, 211, 254);
// genero una palette di colori che mi serviranno alla stampa del testo
$colors[] = imagecolorallocate($img,0,58,104);
$colors[] = imagecolorallocate($img,0,103,150);
$colors[] = imagecolorallocate($img,123,159,221);
// riempo lo sfondo disegnando un rettangolo colorato
// la funzione riceve l'immagine, le cordinate dell'angolo superiore sinistro
// le cordinate dell'angolo inferiore destro e il colore stesso
// cioè i punti della diagonale del rettangolo e il colore di riempimento
// o nel caso della seconda del colore di bordo
imagefilledrectangle($img, 1, 1, $size_x - 2, $size_y - 2, $sfondo);
// disegno il bordo disegnando un rettangolo senza riempimento
imagerectangle($img, 0, 0, $size_x - 1, $size_y - 1, $bordo);
?>
// disegno il testo iterando la stringa di caratteri del codice
for ($i=0; $i<strlen($code); $i++){
$color = $colors[$i % count($colors)];
imagettftext($img,
28+rand(0,8), // il parametro riguarda le dimensioni del font che variano da 28 a 36 punti
-20 + rand(0,40), // angolo di rotazione del testo
($i + 0.3)* $space_per_char, // posizione x di disegno del carattere
50 + rand(0, 10), // posizione y di base del testo
$color, // colore del testo
'arial.ttf', // fonttype da usare
$code{$i}); // carattere da stampare
}
// attivo l'antialiasing sulla immagine in modo da rendere le linee piu morbide
imageantialias($img, true);
// visualizzo l'immagine in formato jpeg
imagejpeg($img, '', 70);
// eventualmente essendo un immagine con lineee geometriche potrei optare per png
// imagepng($img, '', 75);
Ovviamente il font arial dovrà essere incluso nella stessa cartella del file.
Una volta che volessimo utilizzare tale sistema non dovremo far altro che inserire un immagine di questo tipo nella nostra pagina
<?php // genero un captcha code random e lo passo
// il codice generato è una stringa numerica di 6 caratteri
$_SESSION['captcha_code'] = rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9); ?>
<img src="captcha.php" alt="captcha" />
Pag. 34 di 34