Comment structurer des groupes au sein d'un site Web? (Admin, les pouvoirs d'administration, l'identité de l'utilisateur)

StackOverflow https://stackoverflow.com/questions/1527069

Question

Je vais être faire un petit système utilisateur, mais j'ai des questions.

  1. Si je devais faire une table d'inscription (mysql), ce qui ne va pas avec juste stocker le mot de passe et nom d'utilisateur dans la base de données sans cryptage?

  2. Je suis en train de penser à la façon de construire la partie admin. Dois-je vérifier simplement une colonne dans la base de données pour voir si l'utilisateur est admin ou non? Si cela est vrai, alors la page d'administration sera révélé.

  3. Pour les pouvoirs d'administration, disons que j'ai 3 pouvoirs: supprimer l'utilisateur, d'approuver l'utilisateur, et déplacer l'utilisateur. Dans quelques scénarios, je veux donner quelques personnes seulement la capacité d'approuver ou supprimer, ou tout, ou toute combinaison. Comment puis-je faire cela? Je pensais avoir une colonne pour chaque puissance et que le script vérifier chaque colonne. Supposons que j'ai plus de 20 pouvoirs qui seront ajoutés.

  4. Si j'ai un site Web où les gens peuvent créer des groupes et devenir administrateurs de leurs groupes et les ces admins peuvent donner différentes combinaisons de pouvoirs d'administration aux personnes dans leur groupe (Ex, Zack crée et groupe appelé Montagne et subventions un membre la possibilité d'approuver les nouveaux membres du groupe et accorde un second membre la possibilité de supprimer les membres et attribue un troisième membre la possibilité de supprimer et d'approuver. Comment puis-je structurer MySQL? Dois-je utiliser une des colonnes qui disent ce groupe sont-ils admin et ce que la capacité ont-ils des colonnes Ex:. Supprimer, approuver, GroupMemberOf, GroupAdminOf et contrôles d'utilisation

J'ai une idée mais je veux apprendre les moyens plus sophistiqués.

Merci pour les réponses à ce jour, cependant, je suis vraiment des idées sur une structure (Question 2 - 4).. S'il vous plaît laissez-moi savoir si je peux aider à éclaircir la question

Était-ce utile?

La solution

  1. les mots de passe de l'utilisateur Hash avec des sels uniques pour chaque utilisateur, de sorte que lorsque la base de données est accessible par un étranger, ils ne peuvent pas déchiffrer les mots de passe et les mitiger sel attaques de table arc-en-.

2 - 4. Utilisez une table pour les niveaux d'accès (1: membre, 2: modérateur (approbation), 3: admin), et utiliser une autre table différente pour les autorisations d'utilisateur où vous stockez beaucoup à de connexions comme celui-ci :

id (auto_increment)|usr_id|role_id|group_id
-------------------------------------------
1                  |1     |3      |-1
2                  |2     |2      |1
3                  |2     |3      |2
4                  |3     |1      |2

Dans votre cas, l'utilisateur 1 est admin pour tout le site, l'utilisateur 2 est admin pour le groupe 3 et modérateur pour le groupe 2, 3 utilisateur est membre du groupe 2.

[EDIT:]

Quelques réflexions plus sur les pouvoirs pour restreindre les différents rôles: En fonction de votre configuration, vous devez utiliser une application de rôle sur une base par page, par exemple dans un framework MVC, j'étendre le contrôleur de base pour exiger une fonction d'autorisation (rôle) qui doit être appelé à chaque méthode, sinon il doit lancer une exception. Méthodes (pages) qui ne nécessitent pas l'utilisateur de se connecter peut utiliser une autorisation fictive.

Ainsi, la classe d'autorisation ressemblera

class Authorization
{
    public $authorized = false;

    public function dummy()
    {
        $this->authorized = true;
    }

    public function member($usr_id, $group_id = null)
    {
        $sql = "SELECT usr_id FROM usr_roles WHERE usr_id = " . $usr_id . ($group_id !== null) ? " AND group_id " . $group_id : "";
        // count the results of $sql query
        // or some more stuff
        if ($results > 1)
        {
            $this->authorized = true;
        }
        else
        {
            $this->authorized = false;
        } 
    }

    // the other functions
}

Votre nouvelle classe de contrôleur de base ressemblera à ceci:

class BaseController extends Controller
{
    protected $authorization;
    public function __construct()
    {
        $this->authorization = new Authorization();
    }

    public function render()
    {
        if ($this->authorization->authorized === true)
        {
            parent::render
        }
        else
        {
            // redirect to not authorized page 
        }
    }
}

Et enfin à la fin de vos contrôleurs ressemblera à ceci:

class IndexController extends BaseController
{
    // some stuff, methods etc.

    // methods needs logged in user and user must be a member. 
    public function index()
    {
        $this->authorization->member($session_user->getId());
    }
}

[EDIT2:]

Si vous n'êtes pas familier avec la POO, vous pouvez effectuer les opérations suivantes:

Voici une présentation de l'échantillon pour une table de rôles:

role_id|role_name
-----------------
1      |member
2      |moderator
3      |admin

Vous pouvez alors faire une authorize de fonction () à inclure dans tous vos fichiers:

// role_name = "member", "moderator", "admin"
function authorize($usr_id = null, $role_name = null, group_id = null)
{
    // test for user in group and role, return boolean

}

Dans vos fichiers comprennent cette fonction et procédez comme suit

if (authorize($usr_id, "moderator", 2)
{
    // show stuff, if user with $usr_id is moderator for group 2
}
else
{
    // do something else
}
// stuff for all 

Autres conseils

  1. Si vous stockez des mots de passe sans cryptage, vous révèlera tous vos mots de passe du client quand quelqu'un parvient à voler votre base de données, ou d'obtenir un accès en lecture. Malheureusement, la plupart des gens de réutiliser les noms d'utilisateur et mots de passe entre les sites, de sorte que vous faites vos utilisateurs une grande défaveur en ne protégeant pas leurs mots de passe. (Peut-être qu'ils devraient savoir mieux, mais la plupart ne le font pas.)

1) Le stockage des mots de passe en texte clair signifie que si quelqu'un n'avoir accès à votre base de données, ils sait toujours pas le mot de passe. Le battage médiatique autour des mots de passe de salage et de chiffrement est tout à fait stupide, une méthode simple fera très bien pour tout le monde.

$password = "Mypassword";
$salt = "a unique and constant string";
$password = md5($password.$salt);

Ce que cela fait est un mot de passe par encrypte md5();, vous ne pouvez pas obtenir le mot de passe de retour après vous chiffrez avec md5 (). Salant assure également qu'il n'y a aucun moyen de trouver le mot de passe.

Si vous voulez comparer et voir si le mot de passe fonctionne, juste md5 l'entrée de la même manière exactement comme ci-dessous:

$password = "check_this_password";
if(md5($password.$salt) === $originalPassword) 
{ 
    //same password
}

2) Cette question dépend de la façon dont vous souhaitez intégrer des groupes avec le côté admin des choses. S'il n'y a pas d'autres configuration des autorisations du tout, il est sûr de conserver seulement un seul champ dans la base de données avec le niveau du compte. Sinon, utilisez mon prochain point de savoir si elles sont un admin ou non.

3) La façon la plus simple à mettre en œuvre un système d'autorisations est comme cela, il y a d'autres façons, mais il est préférable de ne pas compliquer les choses. Si vous voulez des autorisations pour chaque groupe, vous pouvez ajouter une colonne supplémentaire comme prm_group_id et découvrez chaque utilisateur dans l'autorisation d'un groupe particulier. Mais de toute façon, voici comment cela fonctionne:

Créer une table pour contenir les autorisations

prm_user_id  | prm_permission
   0         | Admin
   0         | Delete
   1         | Add

Chaque ligne est titulaire d'un drapeau ou une autorisation. Ensuite, il est assez simple de savoir si elles ont l'autorisation requise par un peu de SQL et PHP.

function hasPermission($permission, $userID)
{
  $permissions = array();

  $sql = "SELECT prm_permission FROM user_permissions WHERE prm_user_id = $userID";
  $query = mysql_query($sql);

  while($data = mysql_fetch_array($query))
  {
     $permissions[] = $data['prm_permission'];
  }

  //Check if they have a permission with this:
  if(in_array($permission, $permissions))
  {
     return true;
  }
return false;
}

Cela vous permet d'ajouter et de supprimer des autorisations assez facilement, et de vérifier et voir si elles ont une autorisation. Seul inconvénient est des autorisations de gestion peuvent obtenir ABIT délicat.

1 - Je vous suggère de crypter vos mots de passe en utilisant un sel unique pour chaque utilisateur. De cette façon, si votre système est toujours compromized, les mots de passe de vos utilisateurs ne seront pas disponibles pour les pirates (sans plus de piratage de leur part)

http://phpsec.org/articles/2005/password-hashing.html (un peu vieux, mais il a quelques bonnes infos)

2, 3, 4 - Tout cela est possible avec un large éventail de langages web. Je suggère première lecture sur la conception de base de données et déterminer quel type de normalisation et le schéma de table serait idéal pour votre situation. Si vous décidez d'ajouter plus de pouvoirs aux utilisateurs admin à l'avenir, vous pouvez concevoir pour que, dès le début et éviter les maux de tête à l'avenir et être encore au sein de vos besoins actuels.

http://dev.mysql.com/tech -RESSOURCES / articles / intro-à-normalization.html http: //www.peachpit.com/articles/article.aspx?p=30885

  1. Il est évident que le suggéré est de stocker haché, mais il y a des avantages à ne pas le faire aussi bien. Il vient vraiment à ce que vous avez besoin.

2+. J'ai jeté ensemble un petit schéma sql pour cette

En gros, stocker les utilisateurs, les groupes et les permbits dont vous avez besoin dans les tableaux séparés. Ensuite, les utilisateurs associés à des groupes et des autorisations aux utilisateurs des groupes. Pour donner à une personne « tout », vous faites simplement en sorte que votre logique de programmation (soit PHP ou MySQL de proceedure stocké) donne le nouvel utilisateur toutes les autorisations disponibles dans le tableau des autorisations. Pour ce MySQL vous pouvez effectuer une requête comme ceci:

INSERT INTO group_user_permissions
    SELECT `group_user`.`groupid`, `group_user`.`userid`, `permission`.`permbit`
        FROM permission, `group_user`
    WHERE `group_user`.`groupid` = 1
        AND `group_user`.`userid` = 1

insérera toutes les autorisations possibles dans la table de group_user_permission pour groupId et donné (userid dans ce cas GROUPID 1 et userid 1).

Maintenant, où que vous devez vérifier les autorisations que vous pouvez exécuter une requête très simple sur la table de group_user_permission pour voir si cet utilisateur, dans ce groupe, a la permission de faire tout ce qu'ils essaient de faire. C'est finalement souple parce que vous ne devrez pas modifier les tables si vous devez renommer permbits, ajouter permbits ou supprimer permbits.

En outre, en raison de l'utilisation des clés de chaîne dans la table d'autorisation, vous pouvez utiliser ces valeurs dans un format textuel qui fera sens lors de leur lecture (vs en utilisant les numéros de autoincrementing). Faire vos chèques PHP se présentent comme suit:

if( $permbit === "approve" )

vs

if( $permbit === 1 )

Bonne chance!

Je suis un peu en retard dans le jeu pour cela, mais vous aimeriez jeter un oeil à la façon dont CakePHP fait son autorisation. (Si vous utilisez PHP, vous trouverez peut-être que l'utilisation du framework CakePHP vous donne une partie de ce contrôle sans avoir à coder.)

utilisateur-autorisations et CakePHP

De plus, je l'ai trouvé utile de simplement garder une liste d'actions (comme CRUD ou Admin) contre des entités, de sorte que vous aviez en dehors de la table utilisateur normal / mot de passe, vous auriez une table avec les champs comme ci-dessous.

PermID | Deny or Allow | Action | Entity

Vous avez alors une autre table que les groupes cartes à PermId et une autre qui associe les utilisateurs et les groupes (récursive si nécessaire) en groupes (comme les gens ont déjà parlé).

Le refuser ou d'autoriser des moyens que vous pouvez créer ACLs pour permettre l'utilisation ou DACL de refuser l'utilisation si la valeur par défaut est de permettre une action (qui est sans doute pas la meilleure idée normalement), ou s'il y a un petit groupe qui a à refuser l'accès à l'intérieur un plus grand. Vous souhaitez généralement vérifier d'abord s'il y avait un Refuser explicite sur une action contre une entité pour un groupe / utilisateur.

Alors vous pourriez avoir quelque chose comme:

PermID | Type  | Action  | Entity
-------+-------+---------+------------
  1    | Allow | Read    | User_Entry
  2    | Allow | Delete  | User_Entry
  3    | Allow | Move    | User_Entry
  4    | Allow | Approve | User_Entry
  5    | Allow | Create  | User_Entry

Ainsi, à titre d'illustration, un groupe d'administration mapperait aux entrées 1-5, un groupe « utilisateur normal » pourrait à la carte 1 et 5 seulement. (Pour le groupe, lisez « personne » ou « utilisateur » si vous voulez).

Id | Grp    | PermId
---+--------+-----
 1 | Admin  | 1
 2 | Admin  | 2
 3 | Admin  | 3
 4 | Admin  | 4
 5 | Admin  | 5
 6 | Normal | 1
 7 | Normal | 5

Il est évident que cela est facilement extensible quand une nouvelle action ou entité (répertoire par exemple) dans le système! Il est juste un cas d'ajouter les entrées correspondantes dans les tables sans qu'il soit nécessaire de changer le schéma. Vous pouvez utiliser des actions de « All », par exemple, et utiliser un DACL pour une exclusion particulière. Voici un utilisateur de puissance qui peut tout faire, mais supprimer un User_Entry.

PermID | Type  | Action  | Entity
-------+-------+---------+------------
  6    | Allow | All     | User_Entry
  7    | Deny  | Delete  | User_Entry


Id | Grp    | PermId
---+--------+-----
 8 | Power  | 6
 9 | Power  | 7

Dans votre cas, j'imagine que les entités pourraient intégrer le nom du groupe, ou un jeton qui signifie « votre groupe d'appartenance » ou quelque chose par exemple {Homegrp} / UserEntry, plutôt que UserEntry qui sysadmin pourrait avoir.

Désolé si cela était un peu woffley mais j'espère que vous obtenez l'essentiel de celui-ci. (Toutes mes excuses si une réponse précédente a parlé de ce que je ne pense pas que je lis tout le long ...)

Pour les points 2-4, vous voudrez peut-être regarder Role-Based Access Control .

2 .. Oui

3 .. C'est simple si vous avez un nombre fini d'autorisations

4 .. J'ai écrit ce, il y a quelques années, et il est en usage intensif dans une grande entreprise. Contactez-moi si vous voulez plus d'informations sur le schéma.

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