Question

J'ai commencé à développer une application de forum en PHP sur mon framework MVC et j'ai à l'étape où je attribuer des autorisations à des membres. (Par exemple: lecture, écriture, UPDATE, DELETE)

Maintenant, je sais que je peux ajouter 5 colonnes sous la table utilisateur dans ma base de données et les mettre à 1 | 0, mais cela me semble trop si je veux ajouter d'autres règles, comme DEPLACER par exemple.

Et comment puis-je attribuer dynamiquement ces privilèges aux utilisateurs eux individuellement?

J'ai entendu d'utiliser un bitmasks, mais ce serait vraiment bien si je pouvais bien les comprendre avant de continuer.

Avez-vous un exemple de la façon dont je pourrais mettre en œuvre cette?

Était-ce utile?

La solution

La méthode que vous avez décrit - privilèges individuels stockés dans les colonnes -. Est simple au détriment de la flexibilité (comme vous avez remarqué)

La méthode de Zuul est encore plus simple et essentiellement le même que le vôtre, sauf qu'il évite la nécessité pour toutes les déclarations « ALTER TABLE ». Cependant, il n'est pas normalisée, pas facilement interrogeables et non autodocumenté.

Un autre problème avec ces deux méthodes est que votre base d'utilisateurs croît, vous trouverez de plus en plus d'une douleur pour maintenir les privilèges de tout le monde correctement définis. Vous vous retrouverez avec un grand nombre d'utilisateurs qui ont besoin d'exactement les mêmes privilèges. Cependant, afin de modifier les privilèges d'un utilisateur, par exemple pour accueillir un nouveau privilège, vous devrez aller et ajouter ce privilège à chaque utilisateur qui a besoin individuellement. Major PITA.

Pour un forum, il est peu probable que vous aurez besoin pour chaque utilisateur la gestion des privilèges. Il est plus probable que vous aurez certaines catégories d'utilisateurs comme les utilisateurs anonymes, les utilisateurs connectés, modérateurs, administrateurs, etc. Cela rendrait bien adapté pour le contrôle d'accès basé sur les rôles (RBAC). Dans ce système, vous devez attribuer à chaque utilisateur d'un rôle, et accorder des privilèges au rôle. Privilèges seraient stockés sous forme de lignes dans une table « privilège ». de sorte que le schéma de base de données simplifiée ressemblerait à ceci:

PRIVILEGE
int id (primary key)
varchar description

ROLE_PRIVILEGE_JOIN
privilege_id (foreign key)
role_id (foreign key)

ROLE
int id (primary key)
varchar description

USER
int id (primary key)
int role_id (foreign key)

Ce modèle est utilisé dans de nombreuses applications qui traitent avec des privilèges d'utilisateur. Ajouter tous les privilèges que quiconque pourrait avoir comme une ligne dans la table des privilèges; ajouter tous les rôles que tout utilisateur pourrait avoir dans le tableau de rôle; et de les relier de façon appropriée dans la table role_privilege_join.

Le seul inconvénient est que, parce qu'une table de jointure est utilisé, le « X utilisateur peut faire Y » requête va être un peu plus lent.

Autres conseils

A permissions bitmask est mieux compris lorsqu'il est représenté sous forme binaire, avec chaque chiffre représentant une permission d'être activé ou désactivé. Donc, si les autorisations X, Y et Z exist, et je n'ont accès à X et Z, 101 représenterait que je les premier et troisième autorisations accordées pour moi, mais pas la seconde. Le 101 nombre binaire est équivalent au nombre décimal 5, de sorte que ce qui est finirait stocké dans la base de données. Un seul petit entier est un objet beaucoup plus efficace pour stocker qu'une chaîne ou plusieurs petits entiers.

EDIT: J'ai réalisé à quel point il était facile de tirer parti des fonctions de conversion existantes pour obtenir une jolie mise en œuvre rapide va. Voici un exemple.

<?php
function bitmask_expand($n) {
  // 9 returns array(1, 0, 0, 1)
  return str_split(base_convert($n, 10, 2));
}

function bitmask_compact($a) {
  // array(1, 0, 0, 1) returns 9
  return (int) base_convert(implode($a), 2, 10);
}

$ns = range(0, 7);
foreach($ns as $n) {
  print_r($b = bitmask_expand($n));
  echo bitmask_compact($b), "\n\n";
}

Vous pouvez obtenir de meilleures performances si vous utilisez des boucles, plutôt que de tirer en arrière vers et à partir des chaînes, mais cela illustre assez clairement le principe.

Je voudrais créer un tableau intitulé "rôles":

CREATE TABLE Roles(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id),
 rolename VARCHAR(30))

Memory Stick autorisations que vous voulez là-dedans. Ensuite, créez un tableau appelé « UserRoles » aux utilisateurs de lien vers des rôles:

CREATE TABLE UserRoles(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id),
 UserId INT,
 RoleID INT)

Beaucoup de flexibilité et facile à construire sur (c.-à-flux de travail, règles, etc.) (J'ajouter des clés étrangères ainsi)

Vous n'avez pas besoin de compliquer cela, il suffit d'utiliser un champ « ex: permissions » et faire quelque chose comme:

  

$ permissions = "1; 1; 0; 1";

     

où dans votre préoccupation, il se lit comme suit:

     

LIRE - 1 (peut)

     

WRITE - 1 (CAN)

     

Mise à jour - 0 (ne peut pas)

     

DELETE - 1 (CAN)

puis, lors de la vérification, il suffit d'utiliser "Explode" par ";" ...

De cette façon, vous pouvez toujours appliquer plusieurs types d'autorisations sans changer votre table ... ainsi vous obtenez votre table plus petite, et votre requête plus vite!

Il est une solution à votre problème:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top