Une gestion de droits facile à mettre en place

17 octobre 2007 par Julien C. dans Mes astuces

Dans ce premier billet technique, je vais vous parler d’une gestion de droits assez simple sous PHP.
L’utilisation de cet exemple est recommandé pour des petits sites, adapté aussi pour ceux qui utilisent les moteurs de templates par exemple.
L’autre avantage, c’est que cette gestion peut se greffer sur un système existant.

L’objectif est simple, lorsqu’un membre est connecté, il faut savoir s’il a le droit ou pas d’avoir une information ou de faire une action.

Nous allons voir dans un premier temps la structure sql typique d’une table membres et d’une table droits. Puis, nous verrons la fonction magique qui gère simplement ces droits. Enfin, on fera un petit tour d’horizon de tout les petits détails qu’il faut mettre en place pour que ça soit convivial.

La table membres et la table droits

Prenons le cas d’une table membres dont la structure est :


CREATE TABLE `membres` (
`id` int(6) NOT NULL auto_increment,
`email` varchar(120) NOT NULL default '',
`pwd` varchar(32) NOT NULL default '',
`nom` varchar(80) NOT NULL default '',
`prenom` varchar(80) NOT NULL default '',
`droits` varchar(250) default NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

La table membres est composée d’un champ id pour l’identification, puis de divers champs qui servent au stockage des informations du membre.
Le champ qui va nous intéresser est le champ droits, car c’est dans celui-ci que l’on va stocker les identifiants des droits créés.

Pour gérer la table des droits, voici la structure


CREATE TABLE `droits` (
`id` int(11) NOT NULL auto_increment,
`droit` varchar(20) NOT NULL default '',
`valeur` varchar(30) NOT NULL default '',
`description` varchar(250) default NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Ici, toujours un champ id pour l’identification.
Le champ droit contiendra la chaîne de caractère identifiante du droit (beaucoup plus parlant qu’un champ numérique). Exemple : acces_admin
Le champ valeur contiendra la valeur de ce droit. Pour des droits de type booléen, on aura bien souvent true comme valeur. Pour un droit qui contient en fait une valeur numérique (par exemple, le nombre de publication autorisé par un membre par jour), cela sera donc cette valeur qui sera stockée.
Enfin, le champ description permettra de donner du sens au droit concerné pour n’importe quel administrateur.

La structure PHP

Je ne vais pas détailler la façon dont vous contrôler l’accès membre, ni la manière dont vous accédez aux informations d’un membre connecté.
Je pars du principe que le champ membres.droits est stocké dans la variable de sessions $_SESSION[’droits’] sous forme de tableau, exemple :


$_SESSION['droits'] = explode(";",$row_user["droits"]);

Le champ membres.droits doit contenir des numéros séparés par des ; (dans cet exemple)
Les numéros correspondent au champ identifiant de la table droits : id
Si un membre possède le numéro 15 dans sa liste de droits, il aura accès à ce droit.
C’est tout simple.

Maintenant, afin que l’on puisse tester les droits et structurer notre application en conséquence, on va écrire une fonction php qui va parser les droits existants et qui va regarder si le membre est abonné pour chaque droit existant.


function etablish_rights() {
$droits = array();
#Liste droits
$query_droits = "SELECT id,droit,valeur
FROM droits";

$result_droits = mysql_query($query_droits);

while ($row_droits = mysql_fetch_array($result_droits)){
$nom_droit = $row_droits['droit'];
if (in_array($row_droits['id'],$_SESSION['droits']))
{
$droits[$nom_droit] = $row_droits['valeur'];
}
};
return $droits;
}

Cette fonction renvoie un array qui possède comme clé la chaîne identifiante du droit, et pour valeur, la valeur de ce droit. Et ce, uniquement pour les droits dont le membre a accès, donc contenu dans le champ membres.droits.

Ainsi, si on stocke dans une variable $droits le résultat de cette fonction, il suffira de faire comme dans l’exemple suivant pour tester l’accès à l’administration :


if ($droits['access_admin'] == true)
{
//accès admin
}

Si vous assignez la variable $droits à votre moteur de template, cela devient :


{if $droits.access_admin == true}
<!-- Template Admin -->
{/if}

Pour aller plus loin

Comme promis, pour le moment c’est très simple, et aussi … très limité.
Pour administrer ces droits, il est intéressant de créer une table groupe afin d’y stocker un ensemble, un modèle de droits.
Dans ce cas, les droits à valeur numérique prennent toutes leurs utilités.
Exemple :

Soit le droit 10 qui correspond au droit nb_mess et qui a pour valeur 50.
Soit le droit 11 qui correspond au droit nb_mess et qui a pour valeur 20.

Il peut y avoir un groupe admin qui possède la liste de droits suivant : {1;2;3;…;10}
et un groupe membre qui eux, on la liste suivante : {2;5;…;11}
Ainsi, les membres de ces deux groupes n’auront pas le même nombre de messages autorisés.

Niveau administration, il faut prévoir une édition des droits des groupes et une édition des droits d’un membre. De manière globale (on copie/colle une liste de droits d’un groupe) ou de manière individuelle (on édite un par un les droits d’un membre).

Alors, ça vous parle ?

Avez-vous apprécié Une gestion de droits facile à mettre en place? Suivre les billets RSS.
Social Bookmarking
Add to: Digg Add to: Del.icio.us Add to: Technorati Add to: StumbleUpon Add to: Reddit Add to: Slashdot Add to: Netscape Add to: Furl Add to: Newsvine Add to: Yahoo Add to: Google Add to: Blinklist Add to: Spurl Add to: Diigo Add to: Ma.Gnolia

2 Réponses pour “Une gestion de droits facile à mettre en place”

  1. Je connaissais l’école du bitmask, l’école des tables en relation et voilà que tu nous sors une technique à mi chemin entre ces deux là.

    Attention, c’est un débat qui fait rage chez les développeurs ;)

    Duael
  2. Je dois pas être loin de le bonne solution alors ;)

    Julien C.

Participer !

XHTML: Vous pouvez utiliser ces tags : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>