L'ultimo articolo scritto su Sir Bit risale a marzo 2014. La versione che state visitando è un archivio: le pagine sono accessibili come sempre e gli autori potrebbero rispondere ai commenti, ma non saranno inseriti dei nuovi articoli. Visita questa pagina per i dettagli.

PHP – Creare una login sicura e funzionale usando i cookies

Quando si crea un’area di amministrazione, dove un utente qualsiasi può accedere, è indispensabile creare la pagina tenendo conto di due fattori principali:
evitare le query-injections, cioè rendere la vita difficile a eventuali crackers che inviino un codice dannoso che potrebbe intaccare il nostro database
rispettare la privacy e la sicurezza dell’utente, criptandogli la password e stabilendo un tempo massimo in cui l’area di amministrazione resti “aperta”, per impedire che l’utente distratto lasci libero accesso a eventuali malintenzionati che usano il suo computer

In questo tutorial vedremo come creare una semplice login facendo uso dei cookies, dove salvare i dati (username e password dell’utente). Vedremo inoltre quali sono le funzioni da usare per controllare i dati inviati.
In questo esempio di base, si presuppone che gli utenti siano già salvati in un database e che le loro informazioni siano contenute nei tre campi id, username e password. Il campo password contiene la password dell’utente criptata con l’algoritmo md5. Mostreremo solo il codice necessario: eventuali controlli aggiuntivi e la grafica sono a vostra discrezione.

Nota: ricordo che la password andrebbe criptata con un algoritmo più efficace dell’md5. In questo articolo, comunque, non stiamo badando granché alla sicurezza, ma solo alla procedura.

Nel caso (più semplice) che i dati per accedere alla login siano “fissi”, cioè immagazzinati in variabili nella pagina, alcune delle funzioni che andiamo a vedere saranno inutili e quindi dovrete riadattarle di conseguenza.

Download script

Il form di login

Il form di login avrà questo aspetto (la grafica potete adattarla a piacimento con i fogli di stile):

1
2
3
4
5
6
7
8
9
10
11
12
13
<form action="" method="post">
	<div class="login_campo">
		Username:<br />
		<input type="text" class="campo" name="username" />
	</div>
	<div class="login_campo">
		Password:<br />
		<input type="password" class="campo" name="password" />
	</div>
	<div class="login_campo">
		<input type="submit" name="invia" value="Accedi">
	</div>
</form>

I controlli dopo l’invio

Una volta che l’utente ha inserito i dati e inviato il form, facciamo i dovuti controlli. Il codice seguente andrebbe messo nella stessa pagina e prima del form che abbiamo appena visto: infatti, nel caso di errore e qualora lo riteniate necessario, è possibile riportare i dati inseriti dall’utente all’interno degli input o mostrare un messaggio di errore. Nel nostro esempio ignoriamo questa possibilità, ma è bene tenerla presente.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$error=false;
if(isset($_POST['invia'])){

	//recupero i dati dell'utente, se esiste
	$q="select * from utenti where username='".pulisci($_POST['username'])."' and password='".md5(pulisci($_POST['password']))."'";
	$query=mysql_query($q, $db);

	//se i dati inviati al form corrispondono a un utente, allora mi loggo, creo il cookie di sessione e vado a index.php
	if(mysql_num_rows($query)>0){

		$row=mysql_fetch_array($query);

		//immagazzinano le informazioni dell'utente in un array
		$var_session["id"]=$row["id"];
		$var_session["username"]=$row["username"];
		$var_session["password"]=$row["password"];

		//setto la durata del cookies a una settimana
		$time_cookie=3600*24*7;
		setcookie("session", $var_session["username"].'_&&_'.$var_session["password"], time()+$time_cookie);

		//vado a index.php
		header("location: index.php");

	//nessuna corrispondenza con gli utenti: non mi loggo e ritorno al form
	}else
		$error=true;

}

I commenti spiegano gran parte del codice. Riassumendo, cosa abbiamo fatto?

1) Cerco nel database l’utente che ha username e password pari a quelli inseriti dall’utente. Se lo trovo, allora posso settare il cookie di sessione. Da notare che prima del controllo cripto la password inviata dall’utente in md5, in modo da poterla confrontare nel database. La funzione pulisci(), che vediamo tra poco, serve a evitare il passaggio di caratteri dannosi per il database.

2) Immagazzino i dati di accesso dell’utente nell’array $session[]. In questo modo li avrò sempre a disposizione nel caso di bisogno (per esempio per messaggi di benvenuto). Qua va comunque a vostra discrezione: io consiglierei di immagazzinare per lo meno l’id dell’utente in una variabile. In alternativa, sarà possibile recuperare i dati direttamente dai cookies, in un modo meno immediato.
Nota: i dati potrebbero essere salvati in variabili di sessioni (per esempio $_SESSION[“username”]), anziché nell’array visto sopra ($session[]). La scelta è a discrezione del programmatore.

3) Creo il cookies di nome “session”, che contiene l’username e la password dell’utente. Il cookies ha una validità di una settimana (60*60*24*7 secondi), dopodiché l’utente si deve loggare di nuovo. E’ chiaro che se l’utente cancellerà manualmente il cookie di sessione prima della scadenza, dovrà essere ricreato con una nuova login.

4) Reindirizzo l’utente alla pagina index.php, dove avrà accesso al pannello di amministrazione.

Vediamo adesso la funzione per eliminare gli eventuali caratteri pericolosi inviati in fase di login, più o meno consapevolmente dall’utente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function pulisci($login){
	$login=str_replace(";","",$login);
	$login=str_replace(":","",$login);
	$login=str_replace(",","",$login);
	$login=str_replace("'","",$login);
	$login=str_replace("*","",$login);
	$login=str_replace("?","",$login);
	$login=str_replace("=","",$login);
	$login=str_replace("&","",$login);
	$login=str_replace("%","",$login);
	$login=str_replace("$","",$login);
	$login=str_replace("<","",$login);
	$login=str_replace(">","",$login);
	$login=str_replace("#","",$login);
	return $login;
}

Il controllo del cookie di sessione

Il tutorial per il controllo della login è concluso. Prima di chiudere, però, un’ultima annotazione: una volta settati i cookies, come funziona il controllo dell’area di amministrazione? In altre parole, come ci assicuriamo che il cookies sia valido e che l’utente abbia i permessi per accedere?
Ci viene in aiuto un’altra funzione, che deve essere richiamata in ogni pagina:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//funzione per il controllo dei cookies
function controllo_cookie(){

	global $db, $var_session;

	if(isset($_COOKIE['session'])){

		//prendo username e md5(password) presente nel cookie
		$tmp=split("_&&_", $_COOKIE['session']);
		if(count($tmp)!=2)
			return false;

		//confronto username e password del cookie con il database
		$query=mysql_query("select * from utenti where username='".$tmp[0]."' and password='".$tmp[1]."'", $db);

		if(mysql_num_rows($query)>0){
			$row=mysql_fetch_array($query);
			//immagazzinano le informazioni dell'utente in un array
			$var_session["id"]=$row["id"];
			$var_session["username"]=$row["username"];
			$var_session["password"]=$row["password"];
			return true;
		}else
			return false;

	}else
		return false;

}

Nell’ordine:
1) Controllo l’esistenza del cookie di nome “session”.
2) Immagazzino l’username e la password dell’utente (che erano presenti nel cookie, separati dalla stringa “_&&_”) in un array. In questo modo posso estrarli agevolmente.
3) Controllo che l’utente con i dati estratti dal cookie sia esistente nel database.

Adesso non dobbiamo fare altro che eseguire il controllo tramite la funzione, all’inizio di ogni pagina e prima di qualsiasi altra cosa. Se il controllo ha successo (il cookie è trovato e la corrispondenza dati-database è dimostrata), permetto all’utente di proseguire. Altrimenti, se il controllo dà false, reindirizzo l’utente alla pagina di login:

1
2
3
4
5
if(!controllo_cookie()){
	header("location: login.php");
}else{
	//codice da mostrare
}
Etichette
Etichette:, ,
Ultimi Commenti
  1. alberto
  2. paolo
  3. Davide
  4. Davide

Rispondi a Davide Annulla risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.