|
|
|
PROGRAMMAZIONE
WEB
 |
[ 15-11-2002
]
a cura di [ Redazione Internet Magazine] |
Autenticare
gli utenti con PHP
Costruiamo un semplice ma efficace script
per autenticare gli utenti estraendone i dati da un database.
Quello dell’autenticazione degli utenti è da sempre un problema
molto sentito da parte di tutti i webmaster. Inibire l’accesso a
determinate aree del proprio sito può essere necessario per molteplici
motivi. I siti che offrono servizi a pagamento, ad esempio, devono
disporre di zone accessibili soltanto agli utenti registrati. Chi
crea delle aree di amministrazione per il proprio sito (cosa molto
comune, in PHP) avverte chiaramente l’esigenza di proteggere le
pagine con cui gestisce tutto il sito.
Per questi e per tanti altri motivi gli sviluppatori web si adoperano
da sempre creando script o sfruttando le caratteristiche dei vari
web server (Apache in primis) per proteggere files e cartelle dei
propri siti. Anche il PHP interagisce al meglio con i web server
(creando ad esempio dei file .htaccess di Apache) e, cosa di cui
tratteremo in queste pagine, può inviare degli header HTTP al browser
che richiedano nome e password dell’utente. Sfrutteremo questa caratteristica
del PHP per richiedere i dati dell’utente, che cercheremo poi in
un database. Se l’utente esiste permetteremo l’accesso, altrimenti
ne consentiremo l’iscrizione inserendo i nuovi dati nel DB stesso.
Per provare l’esempio di queste pagine ci sarà bisogno di un webserver
Apache, del PHP e di MySQL. Troverete tutti i software necessari
nella sezione “Il meglio” del CD-Rom di questo mese.
A La tabella utenti
|
Visto che conserveremo in un database
i dati degli utenti, la prima cosa da fare è di sicuro quella di
creare il DB stesso e la tabella che conterrà tali dati. La struttura
della tabella sarà molto semplice, formata da soli sei campi:
Id – il campo che fungerà da contatore
Nome – lo username scelto dall’utente
in fase di registrazione
Email – la sua e-mail, che servirà
anche per inviare la password
Password – il campo che conterrà
la password
Data – la data di registrazione
Ip – l’indirizzo IP dell’utente
al momento della registrazione
Dopo aver avviato il server MySQL (si può fare riferimento all’altro
articolo di pratica presente in questo numero) apriamo una sessione
di DOS e, dalla sottocartella bin di MySQL, lanciamo il client
digitando mysql.
Il codice SQL da digitare per creare la nostra tabella (che chiameremo
anagrafica) è il seguente:
CREATE database utenti;
USE utenti;
CREATE TABLE anagrafica (
id int(3) NOT NULL auto_increment,
nome char(8) NOT NULL default '',
email char(255) NOT NULL default '',
password char(8) NOT NULL default '',
data char(255) NOT NULL default '',
ip char(15) NOT NULL default '',
PRIMARY KEY (id),
UNIQUE KEY id (id),
KEY id_2 (id) ) TYPE=MyISAM;
|
è possibile copiare il codice esattamente
come lo si vede; battere il tasto invio alla fine di ogni riga,
non dimenticando di digitare il punto e virgola alla fine, per
dire a mysql che l’istruzione stessa è terminata. I nomi da attribuire
al DB e alla tabella possono essere cambiati a seconda delle prorie
esigenze; l’importante è specificarli nel file di configurazione
che creeremo tra poco.
|
| |
Si comincia col PHP
Ora che abbiamo la tabella nella quale memorizzare i dati,
possiamo iniziare a scrivere un po’ di codice PHP. Stabiliamo,
per essere ordinati, che creeremo tre piccoli script PHP,
in tre diversi file. Il primo conterrà semplicemente i dati
di connessione al database, mentre il secondo invierà gli
header, ed il terzo permetterà di iscriversi agli utenti che
ancora non compaiono nella tabella. La struttra dei tre file
è molto semplice; vediamo dapprima di scrivere il codice del
file di configurazione da includere negli altri due, e che
chiameremo conf.inc.php:
<?
$data = date ("d/m/Y H:i");
|
con l’istruzione date ricaveremo
facilmente la data nel formato GG/MM/AAAA (giorno, mese, anno).
Scriviamo ora i fondamentali dati per connettersi correttamente
al server MySQL:
$server = "localhost";
$utente = "root";
$db_pass = "";
$datab = "gol61";
$tabella = "anagrafica";
|
oltre all’indirizzo dell’host
e i dati dell’utente, abbiamo conservato in due variabili
quelli con il nome del database da utilizzare e quello della
tabella. Volendo personalizzare questi dati sarà sufficiente
intervenire sulle due variabili. Com’è ormai nostra abitudine,
creeremo una piccola funzione al’interno di questo file, chiamata
errore_server(). Questa funzione servirà semplicemente ad
informarci minuziosamente su eventuali errori in fase di connessione
e di interrogazione.
function errore_server()
{
echo "<b>Il database MySql sembra
non rispondere...</b><br>MySql
dice:<br><font color=red>";
echo mysql_error();
echo "</font><br>pregasi
<a href=\"mailto:iltuo@indirizzo.com\">
segnalare</a> il problema";
}
|
A questo punto non dobbiamo fare
altro che connetterci al server e selezionare, direttamente
in questa fase, il database da utilizzare.
$connessione = @mysql_connect ($server, $utente, $db_pass)
or die (errore_server ());
$db = mysql_select_db ($datab, $connessione)
or die (errore_server ());
?>
|
Salviamo il file conf.inc.php
in una cartella del nostro webserver, e pensiamo a creare
quello che sarà l’indice della cartella stessa.
Sei autorizzato? Controlliamo…
Il file index.php avrà l’importantissimo
compito di inviare gli headers e, una volta che l’utente abbia
inserito i dati richiesti, di verificare che questi siano
presenti nel database. Per fare una prova, e visualizzare
tutti gli headers di una richiesta http, possiamo prendere
in prestito un’esempio direttamente dal manuale PHP:
<?
$headers = getallheaders();
while (list ($header, $value) = each ($headers)) {
echo "$header: $value<br />\n";
}
echo $REMOTE_ADDR;
?>
|
Questo piccolo ciclo while approfitta
dell’istruzione getallheaders() per restituire i valori dell’array
definito dall’istruzione stessa. Gli headers sono in realtà
di molteplici tipi, e quello che ci interessa si chiama $PHP_AUTH_USER.
Ricordiamo che gli headers vanno inviati al browser prima
di qualsiasi altra cosa, anche di un solo semplice carattere,
onde evitare spiacevoli errori. Ecco quindi le prime righe
del nostro file index.php
<?
if (!isset($PHP_AUTH_USER)) {
header('WWW-Authenticate: Basic realm="Area privata"');
header('HTTP/1.0 401 Unauthorized');
echo 'Richiesta autorizzazione.';
exit; }
|
|
|
| |
Queste poche istruzioni controllano che il valore
$PHP_AUTH_USER non sia presente nell’ambiente (if (!isset…) e lanciano
la classica finestrella di autenticazione http, dove si dovranno
inserire lo username e la password. In caso di errore ci si limiterà
a stampare a video la frase Richiesta autorizzazione. Qualora l’utente
abbia inserito i dati richiesti, ricorreremo ad un else che ne controllerà
l’esistenza nel DB.
else {
include ("conf.inc.php");
|
ovviamente includeremo all’inizio di
questo ciclo il file che contiene le configurazioni. Subito dopo
penseremo a creare la query e ad eseguirla sul database:
$sql = "SELECT id FROM $tabella WHERE nome='$PHP_AUTH_USER'
and password='$PHP_AUTH_PW'";
$query = mysql_query($sql) or die (errore_server());
|
la query può fornire un solo risultato
o riga (il nome utente deve infatti essere necessariamente univoco).
Controlliamo quindi il suo valore, grazie all’istruzione mysql_num_rows
$num = mysql_numrows($query);
if ($num == 1) {
echo "<P>Ok, sei autorizzato<br>";
echo "Il tuo nome utente è <b>$PHP_AUTH_USER</b><br>";
echo "La tua passwd è <b>$PHP_AUTH_PW</b></p>";
}
|
Se il risultato è uguale ad 1 il nome
utente esiste, e corrisponde alla password digitata. Nell’esempio
abbiamo semplicemente mostrato a video i dati digitati, ma è proprio
qui (all’interno del bracket) che potrete inserire il codice riservato
agli utenti presenti nel DB. È anche plausibile pensare di includere
un file invece di scrivere tutto il codice che serve; si dia un’occhiata
al boxino di queste pagine per approfondire.
else if ($num == 0)
{
echo "Nome utente o password non validi<br>";
echo "<a href=\"iscriviti.php\">iscriviti</a>";
}}
|
Se invece il risultato della query è
uguale a zero visualizzeremo un link che rimanda al file per iscriversi
nel database.
L’iscrizione degli utenti.
Memorizzare gli utenti nel database è meno difficile di quello che
sembra.
Il file iscriviti.php non dovrà far
altro che visualizzare un form HTML e, dopo aver controllato che
lo username inserito non sia già presente, inserire i dati nella
tabella stessa. Dopo avere svolto questo compito, invieremo due
distinte e-mail: una a chi si è appena iscritto, e un’altra al proprietario
del sito stesso, per informarlo della presenza di un nuovo utente.
Creeremo un ciclo if che controlli inizialmente la presenza della
variabile $invia (il nome del pulsante del form HTML). Se questa
non esiste, si visualizza subito il form:
<?
include ("conf.inc.php");
if (!$invia){
echo <<
Il tuo nome utente non è stato trovato nel database
<br>Registrati<br> </h1>
<form method=post>
<table width=85% border=1 align=center> <tr><td>Nome</td>
<td> <input type="text" name="nome"> </td></tr>
<tr> <td>Email</td>
<td><input type="text" name="email"></td> </tr> <tr>
<td>passwd</td>
<td><input type="password" name="passwd"></td>
</tr>
<tr>
<td align=right><input type="submit" name="invia"></td>
<td align=left><input type="reset"></td>
</tr>
</table>
</form>
EOD;
}
|
Da notare che, usando questa “tecnica”,
non abbiamo neanche bisogno di specificare l’action del form stesso.
Se il pulsante viene premuto potremo proseguire con i controlli
del caso e l’eventuale inserimento; vediamo prima se il nome utente
esiste:
else {
$sql = "select * from $tabella where nome='$nome'";
$query =mysql_query ($sql) or die (errore_server());
$num = mysql_numrows($query);
if ($num == 1) {
echo "nome utente già occupato<br>";
echo "<a href=\"javascript:history.back()\">ritenta</a>
con un altro username";
}
|
|
| |
Utilizzando la solita istruzione mysql_numrows controlleremo
il risultato della query e, qualora esso sia maggiore di 0, rimanderemo
indietro l’utente per farlo riprovare con un altro nick.
else {
$ip = $REMOTE_ADDR;
$sql="INSERT INTO anagrafica (id,nome,email,password,
data,ip) VALUES ('', '$nome', '$email',
'$passwd', '$data', '$ip')";
$query = mysql_query ($sql) or die (errore_server());
echo "dati inseriti correttamente<br>";
|
E Inviamo le e-mail
Dopo aver inserito tutti i dati dell’utente nel nostro bravo database,
possiamo pensare a inviare le due e-mail. La prima, come dicevamo,
sarà indirizzata all’utente e conterrà i suoi dati, a mò di promemoria,
e l’altra arriverà al webmaster del sito. Vediamo il codice della
prima mail:
$from_mail = "iltuo@indirizzo.tld";
$To="$email";
$Headers ="From: $from_mail";
$Soggetto="[Inserire nome del sito] I tuoi dati di accesso";
$Corpo.="Ciao!\n\n";
$Corpo.="Sono il programma Sendmail di http://$HTTP_HOST\n";
$Corpo.=" La tua iscrizione è stata accettata!\n\n";
$Corpo.=" Questi sono i tuoi dati:\n\n";
$Corpo.=" Il tuo nome utente: $nome\n";
$Corpo.=" La tua password: $passwd\n\n";
$Corpo.=" A presto!\n\n";
$Corpo.="--------------------------------------------\n";
$Corpo.="$from_mail\n";
$Corpo.="http://$HTTP_HOST\n";
$Corpo.="--------------------------------------------\n";
|
|
La variabile $from_mail conterrà l’indirizzo
che verrà visualizzato come mittente dell’e-mail, e che inseriremo
negli headers della mail (occhio, non sono quelli uguali http…:)
). In $To lo script prenderà l’indirizzo dell’utente per utilizzarlo
come destinatario, mentre in $Soggetto il testo (personalizzabile)
dell’oggetto della mail. Per quanto riguarda il contenuto del messaggio,
esso verrà creato concatenando la variabile $Corpo, in modo da inviare
un messaggio composto da più righe ordinate. Abbiamo inserito nel
corpo anche la variabile d’ambiente $HTTP_HOST, giusto per includere
nel messaggio anche il nome del sito.
mail($To, $Soggetto, $Corpo, $Headers);
echo "ti è stata inviata una mail all'indirizzo
$email con i tuoi dati";
|
Praticamente la stessa cosa sarà da
farsi con l’e-mail da inviare al webmaster del sito.
$webmaster = "iltuo@indirizzo.tld";
$email1 ="$email";
$mailTo1="$webmaster";
$mailHeaders1="From: $email1";
$mailSubject1="[Inserire il nome del sito]
Nuovo UTENTE registrato";
$mailBody1.="Ciao!\n\n";
$mailBody1.="Un nuovo utente si è registrato!\n\n";
$mailBody1.="Questi sono i suoi dati:\n\n";
$mailBody1.="Username: $nome\n";
$mailBody1.="passwd: $passwd\n";
$mailBody1.="Email: $email1\n";
mail($mailTo1, $mailSubject1, $mailBody1, $mailHeaders1);
}}
|
Abbiamo approfittato per chiudere i
cicli ancora aperti; il compito dello script, in realtà, è terminato.
|
|
|