Home > Développement Web > Gérer ses droits et accès utilisateurs en PHP : le Bit Bashing

Gérer ses droits et accès utilisateurs en PHP : le Bit Bashing

Encore un problème récurrent du développeur: dans un CMS, on a une admin avec 10 utilisateurs qui ont avoir des rôles différents, chaque rôle étant autorisé à faire une certaine liste d’actions…
La solution “facile” (et malheureusement, celle qu’on voit quasiment TOUJOURS appliquée) est de créer une table contenant une colonne dans la base de données pour chaque action, plus un champ “user_ID”. Avec nos 4 actions, on a donc une table de 5 champs, qu’on mettra à 0 ou 1 selon que l’utilisateur peut effectuer l’action ou pas.

Problèmes: si on crée une nouvelle action demain, par exemple “éditer la catégorie du post”, on se retrouve avec un schéma de base de donnée à mettre à jour, pour ajouter un champ. Même chose si une action n’existe plus (par exemple si on en regroupe deux: “si on peut valider un post, on pourra aussi toujours l’éditer”). De plus, avec un grand nombre d’utilisateurs et/ou un grand nombre d’actions, on se retrouve avec une table énorme, simplement pour gérer qui peut faire quoi.

Une solution plus élégante serait d’utiliser le Bit Bashing. Cette technique, utilisée pour la gestion des droits sous Unix, permet de regrouper tous les droits d’un utilisateur en UN SEUL chiffre. Pour arriver à cela, chaque action est associée à un nombre, qu’on ne choisit pas au hasard: la suite des nombres est la suite des puissances de 2… Une de ses propriétés mathématiques est que chaque nombre est égal à la somme de tous les précédents, à laquelle on ajoute 1. On a donc bien : 1, 2 (1+1), 4 (2+1+1), 8 (4+2+1+1), 16 (8+4+2+1+1), 32 (16+8+4+2+1+1)…

Sous Unix, voici comment le “nombre” des accès (Lire, Ecrire, Executer) est calculé :
Executer : 1
Ecrire : 2
Lire : 4
(pour une quatrième action, on aurait pris 8, etc)
Puisque chaque nombre est égal à la somme des précédents plus un, on peut ajouter les valeurs sans jamais tomber avec 2 combinaisons différentes sur le même nombre. Par exemple, 5 ne peut être que 4+1, 6 ne peut être que 4+2, 7 ne peut être que 4+2+1.
Pour calculer la valeur de l’accès, on n’a donc qu’à ajouter les valeurs des actions qu’on autorise. Par exemple, pour Lis et Execute (mais n’écris pas), on aura Lis (4) + Execute (1) = 5 (c’est comme ça qu’on calcule le nombre de la commande CHMOD, rien de bien nouveau).

En PHP, on manipule directement les bits (d’où l’utilisation de la notation en base 2) pour profiter des possibilités de comparaisons bit à bit:

  1. define(‘EXECUTER’, 1<<0);
  2. define(‘ECRIRE’, 1<<1);
  3. define(‘LIRE’, 1<<2);
  4.  
  5. $user_rights = 5;
  6. if (LIRE &amp; $user_rights) { echo "LIRE"; } // true
  7. if (ECRIRE &amp; $user_rights) { echo "ECRIRE";} // false
  8. if (EXECUTER &amp; $user_rights) { echo "EXECUTER"; } // true

On aura “LIRE / EXECUTER”. Bien sur, $user_rights doit être pioché dans une base de données ou autre. Avec $user_rights = 4, on aurait eu “LIRE” uniquement, etc.

Et vous, vous faisiez comment, avant de découvrir le Bit Bashing ? ;)

Ce post vous a été utile ? Re-Twittez le ! ReTwittez ce post

Développement Web

  1. | #1

    Ah cool,

    Merci pour ce tuto !

  2. | #2

    Très bonne mise en pratique ;)

  3. | #3

    J’avoue que j’aurais pas pensé le faire comme ça..
    Merci pour l’astuce :)

  4. | #4

    Article très intéressant, merci.

  5. | #5

    Excellent tuto.
    Je n’aurais pas pensé à la comparaison bit à bit génial.

  6. jagogordonne
    | #6

    Bonjour,
    très bon tuto mais j’ai du mal à le mettre en pratique,
    si on prend 9 en binaire sa fais 1001
    comment lui dire en php que neuf
    c’est 0001 soit 1
    et 1000 soit 8
    Merci

  7. Nicolas M.
    | #7

    Quand vous dites : “Avec $user_rights = 4, on aurait eu “LIRE / ECRIRE””, ne faut-il pas plutôt lire qu’on aurais “LIRE” uniquement ?

  8. | #8

    Nicolas M: si, tout à fait. Je corrige tout de suite. Merci !

  1. | #1
  2. | #2