Les badges de l'hôpital
À l'hôpital, la couleur du badge (médecin, infirmier, visiteur) ouvre ou non les portes. On ne programme pas chaque porte pour chaque personne : on donne un rôle à la personne, et des droits au rôle.
Le contrôle d'accès par rôle (RBAC) - rôles, permissions, matrice des droits -, sa mise en œuvre en PHP avec une fonction de contrôle unique appelée en haut de chaque page, le stockage des rôles en base, la séparation des tâches et les erreurs classiques (contrôle oublié, élévation de privilège, rôle modifiable par l'utilisateur).
L'équipe de Souk Atlas grandit : des préparateurs consultent les commandes, une gérante modifie les prix, les clients voient leur compte. Plutôt que d'écrire des conditions partout (« si c'est Leila ou Hamza... »), on regroupe les droits en rôles. C'est la façon standard de gérer les autorisations d'une application.
On ne donne pas les droits à chaque personne : on donne un rôle, et le rôle porte les permissions.
On vérifie une permission, pas un rôle : autoriser('modifier_prix') plutôt que if ($role === 'admin'). Le jour où l’on crée un rôle « responsable catalogue » qui peut aussi modifier les prix, il suffit de mettre à jour la matrice, sans toucher aux pages.
function autoriser(string $permission): void
{
$u = $_SESSION['utilisateur'] ?? null;
if (!$u) {
header('Location: connexion.php');
exit;
}
if (!in_array($permission, PERMISSIONS[$u['role']] ?? [], true)) {
http_response_code(403);
exit('Accès refusé');
}
}
Chaque page protégée commence par une ligne : autoriser('voir_commandes');. Le contrôle est au même endroit partout, facile à relire et à tester.
À l'hôpital, la couleur du badge (médecin, infirmier, visiteur) ouvre ou non les portes. On ne programme pas chaque porte pour chaque personne : on donne un rôle à la personne, et des droits au rôle.
Celui qui encaisse n'est pas celui qui vérifie la caisse le soir. Séparer ces rôles évite qu'une seule personne puisse commettre et cacher une erreur, ou une fraude.
La page s'affichera ici.
Le navigateur demandera /connexion.php au serveur, qui exécutera le PHP et renverra du HTML.
Consignes 0 / 5
Concevez les tables pour stocker utilisateurs, rôles et permissions dans MySQL (un utilisateur peut avoir plusieurs rôles), puis la requête qui dit si l'utilisateur 3 a la permission 'modifier_prix'.
CREATE TABLE roles (id INT AUTO_INCREMENT PRIMARY KEY, nom VARCHAR(30) NOT NULL UNIQUE); CREATE TABLE permissions (id INT AUTO_INCREMENT PRIMARY KEY, code VARCHAR(50) NOT NULL UNIQUE); CREATE TABLE role_permission ( role_id INT NOT NULL, permission_id INT NOT NULL, PRIMARY KEY (role_id, permission_id), FOREIGN KEY (role_id) REFERENCES roles(id), FOREIGN KEY (permission_id) REFERENCES permissions(id) ); CREATE TABLE utilisateur_role ( utilisateur_id INT NOT NULL, role_id INT NOT NULL, PRIMARY KEY (utilisateur_id, role_id), FOREIGN KEY (role_id) REFERENCES roles(id) ); SELECT COUNT(*) > 0 AS autorise FROM utilisateur_role ur JOIN role_permission rp ON rp.role_id = ur.role_id JOIN permissions p ON p.id = rp.permission_id WHERE ur.utilisateur_id = 3 AND p.code = 'modifier_prix';
Le formulaire « Modifier mon profil » envoie prenom, email et telephone. Le script fait UPDATE utilisateurs SET ... avec toutes les clés de $_POST. Quel est le risque, et comment l'éviter ?
Un utilisateur ajoute un champ role=admin à la requête (outils de développement) : le script met aussi à jour la colonne role, et le client devient administrateur. C'est l'« assignation de masse ». Parade : n'accepter qu'une liste blanche de champs modifiables (prenom, email, telephone), et ne changer le rôle que depuis une page réservée aux administrateurs, avec la permission gerer_comptes.