PHP con MySql – Gestire i privilegi degli utenti e creare un sito a livelli di accesso

PHP, MYSQL – Gestire i privilegi degli utenti e creare un sito a livelli di accesso

Poco tempo fa abbiamo visto come creare una login sicura per accedere a un’area di amministrazione.
A questo punto potremmo fare un passo avanti e stabilire, per ogni utente, quali sono le aree in cui può accedere e quali invece nascondergli.

Un campo nel database per gestire i livelli

Possiamo gestire la cosa in due modi.
In un caso, nella tabella utenti (che abbiamo già nel database) aggiungiamo un semplice campo chiamato livello, che conterrà un valore intero. All’utente amministratore daremo il valore “1”, mentre a seguire gli altri utenti avranno un numero superiore, che corrisponde a un privilegio via via più basso.
Ogni livello avrà accesso a determinate aree. L’amministratore, naturalmente, avrà accesso a qualsiasi area, mentre gli utenti del secondo livello, per esempio, potranno accedere a tutto tranne all’area di gestione delle password o della creazione delle fatture. Gli utenti di terzo livello, invece, si vedranno negare anche aree minori come la possibilità di modificare alcuni dati.
Naturalmente, le pagine o le aree di accesso per ogni livello saranno a discrezione del programmatore e potranno essere diverse da sito a sito.
Usando questo metodo, è molto semplice negare l’accesso. Ci basta estrarre il livello dell’utente (per esempio in una variabile di sessione) e fare un controllo a inizio della pagina voluta. In caso di privilegi troppo bassi, si reindirizza all’index o a una qualsiasi altra pagina:
1
2
if($_SESSION['livello']>2)
 header("Location: index.php");
Il metodo è molto semplice, ma in alcuni casi limitante. Se per esempio in futuro avremo la necessità di creare un utente intermezzo al livello 2 e al livello 3 (in pratica, con privilegi superiori al 3 ma inferiori al 2), potremmo essere costretti a modificare del codice o i valori nel database.

Una stringa nel database in binario per gestire gli accessi

Vediamo un metodo più efficace, anche se leggermente più laborioso.

Invece di un valore intero, potremmo salvare all’interno del campo livello una stringa contenente del codice in binario. Ogni posizione (ogni numero) identifica un’azione e il valore (0 o 1) stabilisce se si ha accesso a quell’azione o meno.
Facciamo un esempio. Stabiliamo che la prima posizione si riferisca all’area “gestione utenti”, la seconda a “gestione fatture” e la terza a “visualizzazione dati”. A ognuna di queste sezioni corrisponde un’area del sito, una parte di pagina o un’azione (a vostra discrezione). Per “gestione utenti”, per esempio, uno 0 impedirà di accedere alla pagina che gestisce gli utenti. Per “visualizzazione dati”, invece, uno 0 impedirà la vista di una parte di pagina in cui si mostra l’elenco dei dati.
Adesso prendiamo quattro utenti fittizi (già presenti nella tabella utenti) e compiliamo il loro campo livello rispettivamente con queste stringhe:
Campo per l’utente A: 111
Campo per l’utente B: 011
Campo per l’utente C: 001
Campo per l’utente D: 001
Traducendo in parole:
L’utente A visualizza tutte e tre le sezioni (ha tutte le posizioni a 1).
L’utente B può gestire le fatture e visualizzare i dati, ma non può gestire gli utenti (la prima posizione è a 0).
Gli utenti C e D possono soltanto visualizzare i dati.
In caso di aggiunta di un’altra sezione, dovremmo creare un ulteriore 0 o 1 in fondo alla stringa del campo livello. Per esempio, potremmo aggiungere la quarta posizione “gestione pagine del sito”. Di conseguenza gli utenti saranno modificati in questo modo:
Utente A: 1111
Utente B: 0110
Utente C: 0010
Utente D: 0010
Potenzialmente non esiste limite alla quantità di aree gestibili in questo sistema e non vengono intaccati i precedenti permessi.

Come controllare l’accesso a un’area

Adesso ci sarà utile la funzione per controllare se l’utente ha effettivamente accesso all’area o all’azione richiesta.
1
2
3
4
5
6
7
8
9
//estrae il valore della posizione-livello passata: true se è 1 (attivo), false se è 0
function livelli_valore($posizione){
 $char=$_SESSION["livello"][$posizione-1];
 return $char;
}

//funzione da richiamare a inizio pagina o all'interno dell'area da controllare
if(!livelli_valore(2)){
 header("Location: index.php");
}
In questo caso ho controllato la seconda posizione della stringa, cioè “gestione fatture”. Se risulta uno 0, l’utente non può accedere (utenti C e D) e viene reindirizzato all’index. Altrimenti lo script nel resto della pagina viene eseguito (utenti A e B).
Quello che abbiamo visto è la base per la gestione di un sistema a livelli. E’ possibile, naturalmente, (e auspicabile) creare una pagina ad hoc per cambiare i permessi degli utenti o per aggiungere una sezione senza dover intervenire direttamente nel database.

Esempio

Riassumiamo i concetti, facendo un esempio concreto (e minimale: dovranno essere apportate le dovute integrazioni, dove c’è bisogno).
Inseriamo nel database una tabella user_livelli, che conterrà il nome delle pagine e la loro posizione nella stringa dei livelli utente:
1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE IF NOT EXISTS `user_livelli` (
  `id` int(11) NOT NULL auto_increment,
  `posizione` int(3) NOT NULL,
  `nome` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

INSERT INTO `user_livelli` (`id`, `posizione`, `nome`) VALUES
(1, 1, 'Amministratore (solo supervisore)'),
(2, 2, 'Fatture di acquisto'),
(3, 3, 'Fatture di vendita'),
(4, 4, 'Riepilogo fatture');
La nostra tabella utenti sarà di questo tipo (al posto dei […] ci potranno esserci altri campi a piacere, come il nickname):
1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(255) NOT NULL default '',
  `password` varchar(32) NOT NULL default '',
  [...]
  `livello` varchar(200) NOT NULL default '0',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

INSERT INTO `user` (`id`, `username`, `password`, [...] `livello`) VALUES
(1, 'Admin', 'password_criptata', [...] '1000'),
(2, 'Utente1', 'password_criptata', [...] '0110'),
(3, 'Utente2', 'password_criptata', [...] '0001');
Il campo livello del database contiene una stringa, che si collega immediatamente con il campo posizione della tabella user_livelli. Come notate, infatti, la stringa ha quattro cifre (in binario) e la tabella user_livelli contiene esattamente quattro tipologie di livello.
L’Admin, nel nostro caso, una volta che accederà avrà soltanto il potere di supervisore (solo la posizione 1 è attiva, le altre gli sono negate). L’Utente1, invece, potrà gestire le fatture di acquisto e di vendita, ma non potrà vedere il riepilogo delle fatture (posizione 2 e 3 attive, posizione 4 disattivata).
Una volta impostate le basi nel database, vediamo come è possibile integrarle nel sito. Poniamo il caso di avere due pagine, chiamate fatture_vendita.php e utenti.php. La prima permette di gestire le fatture di vendita, la seconda mostra l’elenco degli utenti registrati.
Noi vogliamo fare in modo che gli utenti siano visibili soltanto all’amministratore. All’inizio della pagina utenti.php inseriamo quindi il controllo che abbiamo viso sopra:
1
2
if(!livelli_valore(1)){
 header("Location: index.php");
}
In pratica, controlliamo che l’utente abbia attiva la posizione 1 nel database: in tal caso si può proseguire e vedere l’elenco degli utenti; in caso contrario, si viene reindirizzati alla homepage.
Nel nostro esempio, solo l’utente Admin ha la prima posizione attiva (la prima cifra della stringa a 1), quindi lui soltanto potrà accedere alla pagina.
Lo stesso concetto si farà per la pagina fatture_vendita.php, ma in questo caso il controllo dovrà essere fatto sulla terza posizione:
1
2
if(!livelli_valore(3)){
 header("Location: index.php");
}
L’Utente2 potrà accedere alla pagina, mentre tutti gli altri utenti si vedranno reindirizzare a index.php.

fonte originale: http://www.manuelmarangoni.it/sir-bit/420/php-mysql-gestire-i-privilegi-degli-utenti-e-creare-un-sito-a-livelli-di-accesso/

Commenti