Как структурировать группы на веб-сайте? (администратор, полномочия администратора, удостоверение пользователя)


Я собираюсь создать небольшую пользовательскую систему, но у меня есть вопросы.

  1. Если бы я должен был создать таблицу регистрации (mysql), что плохого в том, чтобы просто сохранить пароль и имя пользователя в базе данных без шифрования?

  2. Я пытаюсь придумать, как создать административную часть. Должен ли я просто проверить столбец в базе данных, чтобы узнать, является ли пользователь администратором или нет? Если это правда, то откроется страница администратора. 

  3. Что касается полномочий администратора, допустим, у меня есть 3 полномочия: удалить пользователя, утвердить пользователя и переместить пользователя. В некоторых сценариях я могу захотеть предоставить некоторым людям возможность только утверждать, или удалять, или все, или любую комбинацию. Как бы я это сделал? Я подумывал о том, чтобы иметь столбец для каждой мощности и чтобы сценарий проверял каждый столбец. Давайте предположим, что у меня есть более 20 полномочий, которые будут добавлены.

  4. Если у меня есть веб-сайт, где люди могут создавать группы и становиться администраторами своих групп, и эти администраторы могут предоставлять различную комбинацию полномочия администратора для людей в их группе (например, Зак создает группу под названием Mountain и предоставляет одному участнику возможность утверждать новых участников группы, а второму участнику - возможность удалять участников и назначает третьему участнику возможность удалять и утверждать. Как я буду структурировать это в MySQL? Должен ли я использовать столбцы, в которых указано, в какой группе они являются администраторами и какие у них есть возможности? Например, столбцы: Удалить, Утвердить, Член группы, администратор группы и использовать проверки.

У меня есть идея, но я хочу научиться более изощренным способам.

Спасибо за ответы до сих пор, однако я действительно ищу идеи по структуре (вопрос 2 - 4 ). Пожалуйста, дайте мне знать, если я смогу помочь прояснить этот вопрос.

Author: Strawberry, 2009-10-06

8 answers

  1. Хэшируйте пароли пользователей с уникальными солями для каждого пользователя, чтобы, когда к вашей базе данных может получить доступ посторонний, они не могли расшифровать пароли, а соль смягчает атаки радужных таблиц.

2 - 4. Используйте таблицу для уровней доступа (1: участник, 2: модератор (утверждение), 3: администратор) и используйте еще одну другую таблицу для разрешений пользователей, в которой вы храните соединения "многие ко многим", например:

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

В вашем случае пользователь 1 является администратором для весь сайт, пользователь 2 является администратором группы 3 и модератором группы 2, пользователь 3 является членом группы 2.

[ РЕДАКТИРОВАТЬ:]

Еще несколько мыслей об ограничении полномочий для разных ролей: В зависимости от вашей настройки вы должны использовать некоторое принудительное исполнение ролей для каждой страницы, например, в рамках MVC, я бы расширил базовый контроллер, чтобы требовать (роли) функции авторизации, которая должна вызываться для каждого метода, в противном случае она должна выдавать исключение. Методы (страницы), которые делают не требующий от пользователя входа в систему может использовать фиктивную авторизацию.

Таким образом, класс авторизации будет выглядеть как

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
}

Ваш новый базовый класс контроллера будет выглядеть следующим образом:

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 
        }
    }
}

И, наконец, в конце концов ваши контроллеры будут выглядеть так:

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());
    }
}

[ ПРАВКА2:]

Если вы не знакомы с ООП, то вы можете сделать следующее:

Вот пример макета таблицы ролей:

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

Затем вы можете создать функцию авторизовать() для включения во все ваши файлы:

// 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

}

В ваших файлах включите эту функцию и выполните следующие действия

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 
 5
Author: Residuum, 2009-11-03 11:40:54
  1. Если вы храните пароли без шифрования, вы будете раскрывать все пароли ваших клиентов, когда кому-то удастся украсть вашу базу данных или получить доступ к ней для чтения. К сожалению, большинство людей повторно используют имена пользователей и пароли между сайтами, поэтому вы сильно обижаете своих пользователей, не защищая их пароли. (Может быть, им следовало бы знать лучше, но большинство из них этого не знают.)
 3
Author: Peter Recore, 2009-10-06 18:00:27

1) Хранение паролей с открытым текстом означает, что если кто-то получит доступ к вашей базе данных, он все равно не будет знать пароль. Шумиха вокруг соления и шифрования паролей довольно глупа, простой метод подойдет любому.

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

Что это делает, так это шифрует пароль через md5();, вы не можете получить пароль обратно после того, как зашифруете его с помощью md5(). Засаливание также гарантирует, что невозможно просто найти пароль.

Если вы хотите сравнить и посмотрите, работает ли пароль, просто введите md5 точно так же, как показано ниже:

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

2) Этот вопрос зависит от того, как вы хотите интегрировать группы с административной стороной вещей. Если другие разрешения вообще не настроены, безопасно просто сохранить одно поле в базе данных с уровнем учетной записи. В противном случае используйте мой следующий пункт, чтобы узнать, являются ли они администраторами или нет.

3) Самый простой способ реализовать систему разрешений выглядит следующим образом: другими способами, но лучше не усложнять это. Если вам нужны разрешения для каждой группы, вы можете добавить дополнительный столбец, например prm_group_id, и узнать разрешения каждого пользователя в определенной группе. Но в любом случае, вот как это работает:

Создайте таблицу для хранения разрешений

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

Каждая строка содержит флаг или разрешение. Тогда довольно просто узнать, есть ли у них необходимое разрешение, используя немного SQL и 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;
}

Это позволяет добавлять и удалять разрешения довольно легко, а также проверить и посмотреть, есть ли у них разрешение. Единственным недостатком является то, что управление разрешениями может быть довольно сложным.

 3
Author: Sam, 2009-11-03 11:36:59

1 - Я бы посоветовал вам зашифровать свои пароли, используя уникальную соль для каждого пользователя. Таким образом, если ваша система когда-либо будет взломана, пароли ваших пользователей не будут доступны хакерам (без дальнейшего взлома с их стороны)

Http://phpsec.org/articles/2005/password-hashing.html (немного старый, но имеет хорошую информацию)

2, 3, 4 - Все это возможно с помощью широкого спектра веб-языков. Я бы предложил сначала ознакомиться с дизайном базы данных и выяснить какая схема нормализации и таблицы была бы идеальной для вашей ситуации. Если вы решите добавить больше полномочий пользователям-администраторам в будущем, вы можете разработать для этого с самого начала и избежать каких-либо головных болей в будущем и по-прежнему соответствовать вашим текущим требованиям.

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

 0
Author: NinjaBomb, 2009-10-11 18:26:09
  1. Очевидно, что предлагается хранить его в хэшированном виде, но есть и преимущества в том, чтобы этого не делать. Это действительно сводится к тому, что вам нужно.

2+. Я собрал небольшую схему sql для этого здесь

В основном, храните пользователей, группы и необходимые вам разрешения в отдельных таблицах. Затем свяжите пользователей с группами и предоставьте разрешения пользователям в группах. Чтобы дать человеку "все", вы просто убедитесь, что ваша логика программирования (либо PHP, либо Сохраненный в MySQL порядок действий) предоставляет новому пользователю все доступные разрешения в таблице разрешений. Чтобы выполнить это в MySQL, вы можете выполнить запрос следующим образом:

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

Это вставит все возможные разрешения в таблицу group_user_permission для заданных идентификаторов группы и пользователя (в данном случае идентификатор группы 1 и идентификатор пользователя 1).

Теперь, когда вам понадобится проверить разрешения, вы можете выполнить очень простой запрос к таблице group_user_permission, чтобы узнать, является ли этот пользователь в этом группа, имеет разрешение делать все, что они пытаются сделать. Это в конечном счете является гибким, потому что вам не придется изменять таблицы, если вам нужно переименовать пермбиты, добавить пермбиты или удалить пермбиты.

Кроме того, из-за использования строковых ключей в таблице разрешений вы можете использовать эти значения в текстовом формате, который будет иметь смысл при их чтении (по сравнению с использованием автоматически вводимых чисел). Чтобы ваши проверки PHP выглядели так:

if( $permbit === "approve" )

Против

if( $permbit === 1 )

Хорошо удачи!

 0
Author: Kevin Peno, 2009-11-03 00:56:09

Я немного опоздал в игру из-за этого, но вы, возможно, захотите взглянуть на то, как CakePHP выполняет свою авторизацию. (Если вы используете PHP, вы можете обнаружить, что использование фреймворка CakePHP дает вам часть этого контроля без необходимости его кодирования.)

Разрешения пользователя и cakephp

Кроме того, я счел полезным просто сохранить список действий (таких как CRUD или Admin) против сущностей, чтобы, помимо обычной таблицы пользователей/паролей, у вас была таблица с поля, как показано ниже.

PermID | Deny or Allow | Action | Entity

Затем у вас есть другая таблица, которая сопоставляет группы с PermId, и другая, которая сопоставляет пользователей и группы (рекурсивно, если необходимо) в группы (как люди уже говорили).

Запретить или Разрешить означает, что вы можете создать списки управления доступом, чтобы разрешить использование, или списки DACL, чтобы запретить использование, если по умолчанию разрешено действие (что, вероятно, обычно не лучшая идея), или если есть меньшая группа, которой нужно запретить доступ в большей. Обычно вы сначала проверяете, чтобы увидеть если было явное запрещение действия против сущности для группы/пользователя.

Таким образом, у вас может быть что-то вроде:

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

Таким образом, в качестве иллюстрации группа администраторов будет отображаться на записи 1-5, группа "обычный пользователь" может отображаться только на 1 и 5. (Для группы прочитайте "лицо" или "пользователь", если хотите).

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

Очевидно, что это легко расширяется, поскольку, когда в системе возникает новое действие или объект (например, каталог), это просто случай добавления соответствующих записей в таблицы без необходимости менять схему. Вы можете использовать действия "Все", например, и использовать список DACL для определенного исключения. Вот опытный пользователь, который может делать все, кроме удаления входа пользователя.

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


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

В вашем случае я бы предположил, что Сущности могут включать имя группы или какой-либо токен, который будет означать "ваша домашняя группа" или что-то, например, {homegrp}/userentry, а не просто имя пользователя, которое может быть у системного администратора.

Извините, если это было немного по-дурацки, но я надеюсь, что вы поняли суть об этом. (Прошу прощения, если в каком-либо предыдущем ответе говорилось об этом, так как я не думаю, что прочитал все до конца...)

 0
Author: Trevor Tippins, 2009-11-03 01:58:56

Для пунктов 2-4 вы можете посмотреть Управление доступом на основе ролей.

 0
Author: hrnt, 2009-11-03 11:46:30

2.. Да

3.. Это просто, если у вас есть конечное число разрешений

4.. Я написал это пару лет назад, и оно активно используется в крупной компании. Свяжитесь со мной, если вам нужна дополнительная информация о схеме.

 -1
Author: gahooa, 2009-10-06 18:07:32