Premessa
Quando non siamo su una connessione protetta parlare di un login sicuro é praticamente inutile.
Quello che possiamo fare però è tentare quanto più ci è possibile di rendere difficile l' accesso ai malintenzionati e di salvaguardare i dati dell' utente.
La scelta di Ajax è del tutto di convenienza mentre i concetti potrebbero essere analoghi per un' applicazione simile in Flash.
Perche' Ajax
Lo scopo e' quello di filtrare ancora prima di inviare le info al server i dati sensibili dell' utente.
E' pratica comune controllare o hashare in md5 utente e password solo dopo l' invio dei dati alla pagina php che dovrebbe filtrare i furboni che vorrebbero accedere ad un' area protetta senza autorizzazione.
Con questo metodo possiamo non solo evitare di inviare in chiaro dati durante la richiesta di accesso ma possiamo anche evitare di far elaborare una pagina piu' o meno complessa addetta allo scopo attraverso un'altra dedicata e potenzialmente ottimizzata, grazie al poco codice usato e alla poca memoria utilizzata.
Va comunque sottolineato che a prescindere dal metodo, se non siamo in un' area protetta, un malizioso potrebbe riuscire lostesso ad intercettare tali dati, ma come ho già detto, non riuscirebbe ad intercettarli puliti.
In ultimo, siccome e' di oggi la notizia sul blog che Ajax "può essere pericoloso", ho scelto proprio questa teconologia (ed ultimato questa pillola) proprio per farvi capire che in realtà Ajax puo' essere addirittura piu' sicuro, se usato in modo sensato.
Di cosa abbiamo bisogno lato client ?
Per prima cosa di un browser decente e soprattutto recente, in grado di sfruttare la tecnologia asincrona di Ajax.
Poi abbiamo bisgono di:
In ultimo, ma non per utilità, abbiamo bisogno di una pagina dove inserire lo pseudo form per effettuare il login.
Per venire in contro a tutte le esigenze ho scritto un codice XHTML 1.1 , CSS2 e WCAG 1.0 , cosi' da non aver problemi di contesto.
index.html ( o login.html o quello che e' insomma )
codice:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it" >
<head>
<title>Ajax Login Example</title>
<script type="text/javascript" src="md5.js"></script>
<script type="text/javascript" src="LoadVars.js"></script>
<script type="text/javascript" src="Login.js"></script>
<style type="text/css">
label {
display: none;
}
#login {
padding: 2px;
width: 260px;
border: 1px solid #DDD;
background-color: #EFEFEF;
text-align: center;
}
#uname, #upass {
width: 80px;
margin-right: 8px;
font-family: Verdana, Helvetica, sans-serif;
font-size: 8pt;
border: 1px solid #E5E5E5;
}
#logbtn {
border: 0px;
background: url(login.gif) no-repeat;
width: 59px;
height: 23px;
}
</style>
</head>
<body onload="logInit('uname', 'upass', 'logbtn');">
<div id="login">
<label for="uname">User name</label>
<input id="uname" type="text" value="user" />
<label for="upass">User password</label>
<input id="upass" type="text" value="password" />
<label for="logbtn">Login button</label>
<input id="logbtn" type="button" value="" />
</div>
</body>
</html>
Questi sono i tasti di esempio login.gif e login2.gif

A questo punto potete già leggervi il file Login.js il quale é commentato appositamente per capire quale é la procedura e come va sfruttata.
Ovviamente resto a disposizione per dubbi su quanto viene fatto, ma soprattutto per consigli la dove si potrebbe migliorare l'affidabilità del sistema proposto ( vale anche per la parte in php ) .
Di cosa abbiamo bisogno lato server ?
Ovviamente di PHP almeno 4.3.0 , uno spazio dove poter fare i nostri tests e:
codice:
1 - File con una funzione ( o anche piu' funzioni a seconda delle esigenze )
in grado di verificare l' autenticita' dei dati e di restituirci un riscontro sugli stessi
2 - File con le operazioni da effettuare per il login "trasparente"
3 - Uno o piu' files per la nostra area protetta
L' ideale sarebbe appoggiare la funzione ad un database, ma teoricamente sarebbe possibile sfruttare il sistema anche con gestioni su filesystem.
Ora andiamo a vedere nel dettaglio questi files e seguiamo i commenti esplicativi.
validUser.php ( il file con la funzione di verifica dati )
codice:
<?php
// funzione per verificare se in database esiste un
// utente con questo nome e questa password
// entrambi devono essere degli hash md5
function validUser(&$user, &$pass) {
// imposto il valore di ritorno
$result = false;
// verifico l' hash md5 dei dati
if(preg_match("/(?i)^[a-f0-9]{32}$/", $user, $pass)) {
// effettuo la query in database ... non in questo esempio
$query = 'SELECT id FROM table WHERE MD5(user) = "'.$user.'" AND MD5(pass) = "'.$pass.'"';
// ovviamente solo se avro' un riscontro di un record ...
$result = true;
}
return $result;
}
?>
login.php ( il file di gestione autenticazione )
codice:
<?php
// includo il file validUser
require('validUser.php');
// verifico che i valori user e pass siano stati postati
// solo in questo caso faccio le mie operazioni, altrimenti é inutile
if(isset($_POST['user'], $_POST['pass'])) {
// se l'utente esiste ed é valido
if(validUser($_POST['user'], $_POST['pass'])) {
// imposto il cookie utente e pass e li faccio scadere
// alla chiusura del browser
setcookie('authentication', $_POST['user'].'|'.$_POST['pass'], 0, '/');
// imposto il risultato su OK
$output = '&result=OK';
}
else // imposto un output errato
$output = '&result=NO';
// headers per evitare problemi di cache
header('Content-Length: '.strlen($output));
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
echo $output;
}
?>
ok.php ( la pagina protetta dal sistema )
codice:
<?php
// includo il file validUser
require('validUser.php');
// se l' utente ha il cookie ed e' splittabile ed ha 2 soli elementi
// e passa il controllo in database ...
if(
isset($_COOKIE['authentication']) &&
(strpos($_COOKIE['authentication'], '|') !== false) &&
(@$dati = explode('|', $_COOKIE['authentication'])) &&
count($dati) === 2 &&
validUser($dati[0], $dati[1])
) {
// ... continuiamo con il nostro script protetto
echo "<h1>Benvenuto utente loggato.</h1>";
}
else
// altrimenti l' utente e' un fagiano o un furbo che ci prova,
// rimandiamolo al login
header('Location: index.html');
?>
Come è facile notare i nomi sono modificabili, basta seguire il file Login.js e correggere eventuali redirect per riadattare come volete questo sistema.
Un test funzionante é visionabile al seguente indirizzo ma non richiede una vera e propria autenticazione:
http://www.3site.it/LOGIN/
Ora tocca a voi insultarmi, migliorare il sistema o fare domande