 
    Привет друзья. Хочу поговорить с вами о методе разграничения прав пользователей на сайте, а точнее о ролях пользователей.
Роль пользователя это совокупность прав и разрешений выданные той или иной роли описанной в информационной системе.
Так вот, на любом форуме вы встречали администраторов, модераторов, гостей и т.д. Все это и есть роли. Каждая из ролей отвечает своим задачам и имеет свои привилегии. В Web приложениях роли создаются программистом, он сам создает роли и описывает их права.
Самые распространённые роли это:
- Администратор
- Модератор
- Пользователь
- Гость
И так друзья, что мы сможем делать с помощью ролей на нашем сайте? А все что угодно. Например вы можете показывать какую-то часть контента не зарегистрированному пользователю. Если пользователь прошёл регистрацию и авторизовался в системе, то его привилегии увеличиваются в плане доступа к контенту и он уже может просматривать более подробный контент вашего ресурса (например фотогалерею, оставлять комментарии и т.д). Все зависит от вашей фантазии и того что хотите показать пользователю или на оборот спрятать от него.
Переходя от слов к делу нам понадобится - Регистрация пользователей PHP MySQL с активацией письмом . Данный скрипт в версии с PDO мы будем модернизировать для создания авторизации с ролью пользователя. Мы немного модернизируем нашу табличку где у нас хранятся пользователи. Создадим еще две таблички – это таблица ролей пользователей и таблица с контентом.
И так, создадим таблицы в нашей базе данных. У меня это таблицы:
- Bez_reg
- Bez_role
- Bez_content
В таблице bez_reg в конце добавляем поле role , где собственно и будет привязка пользователя к роли.
  
    --
    -- Table structure for table `bez_reg`
    --
    CREATE TABLE IF NOT EXISTS `bez_reg` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `login` varchar(200) NOT NULL,
    `pass` varchar(32) NOT NULL,
    `salt` varchar(32) NOT NULL,
    `active_hex` varchar(32) NOT NULL,
    `status` int(1) NOT NULL,
    `role` tinyint(4) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
  
Далее создаем таблицу bez_role , где напишим названия наших ролей:
- Администратор
- Модератор
- Пользователь
    
      --
      -- Table structure for table `bez_role`
      --
      CREATE TABLE IF NOT EXISTS `bez_role` (
      `id_role` tinyint(4) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) NOT NULL,
      PRIMARY KEY (`id_role`)
      ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
    
  
Данный трех ролей нам будет достаточно, чтобы система ролей работала. Создаем третью таблицу bez_contnet , здесь будет храниться контент и роли пользователей которым можно просматривать данный контент.
      
        --
        -- Table structure for table `bez_content`
        --
        CREATE TABLE IF NOT EXISTS `bez_content` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `content` text NOT NULL,
        `role` varchar(255) NOT NULL,
        PRIMARY KEY (`id`)
        ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
      
    
С таблицами разобрались, теперь нужно нам сделать себя администраторами т.к. по идее при импорте базы данных у вас должна быть учетная запись по умолчанию с ролью администратор, но так как мы делаем все сами, то нам не лень залезть в базу и сделать себя админом )).
Регистрируемся через форму регистрации, активируем свой аккаунт изменив поле status = 1 и делаем себя администратором установив в поле role = 1 .
Далее заполняете таблицу bez_contnet , произвольным текстом, при этом в поле role через запятую указываете те роли которым разрешен доступ на просмотр данного контента. У меня администратор может просматривать все статьи, модератор только первую статью, пользователь только вторую статью.
С созданием нужных таблиц разобрались, теперь нужно немного поправить скрипт авторизации. Для это переходим в папку ./scripts/auth/auth.php ищим запрос к базе данных
  
    SELECT *
    FROM `'. BEZ_DBPREFIX .'reg`
    WHERE `login` = :email
    AND `status` = 1;
  
Заменяем на новый запрос к базе данных
  
    SELECT * FROM `'. BEZ_DBPREFIX .'reg` AS `u`
    LEFT JOIN `'. BEZ_DBPREFIX .'role` AS `r` ON `u`.`role` = `r`.`id_role`
    WHERE `login` = :email
    AND `status` = 1
  
Далее добавляем нужные сессионые переменные для работы с авторизированным пользователем.
  
    //Переменные для работы с залогиненым пользователем!
    $_SESSION['user']   = true;
    $_SESSION['login']  = $_POST['email'];
    $_SESSION['role']   = $rows[0]['role'];
    $_SESSION['name']   = $rows[0]['name'];
  
В итоге файл auth.php должен быть таким:
  
<?php
 /**
 * Обработчик формы авторизации
 * Site: https://bezramok-tlt.ru
 * Авторизация пользователя
 */
 //Выход из авторизации
 if(isset($_GET['exit']) == true){
    //Уничтожаем сессию
    session_destroy();
    //Делаем редирект
    header('Location:'. BEZ_HOST .'?mode=auth');
    exit;
 }
 //Если нажата кнопка то обрабатываем данные
 if(isset($_POST['submit']))
 {
    //Проверяем на пустоту
    if(empty($_POST['email']))
        $err[] = 'Не введен Логин';
    if(empty($_POST['pass']))
        $err[] = 'Не введен Пароль';
    //Проверяем email
    if(emailValid($_POST['email']) === false)
        $err[] = 'Не корректный E-mail';
    //Проверяем наличие ошибок и выводим пользователю
    if(count($err) > 0)
        echo showErrorMessage($err);
    else
    {
        /*Создаем запрос на выборку из базы
        данных для проверки подлиности пользователя*/
        $sql = 'SELECT * FROM `'. BEZ_DBPREFIX .'reg` AS `u`
            LEFT JOIN `'. BEZ_DBPREFIX .'role` AS `r` ON `u`.`role` = `r`.`id_role`
            WHERE `login` = :email
            AND `status` = 1';
        //Подготавливаем PDO выражение для SQL запроса
        $stmt = $db->prepare($sql);
        $stmt->bindValue(':email', $_POST['email'], PDO::PARAM_STR);
        $stmt->execute();
        //Получаем данные SQL запроса
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        //Если логин совподает, проверяем пароль
        if(count($rows) > 0)
        {
            //Получаем данные из таблицы
            if(md5(md5($_POST['pass']).$rows[0]['salt']) == $rows[0]['pass'])
            {
                //Переменные для работы с залогиненым пользователем!
                $_SESSION['user']   = true;
                $_SESSION['login']  = $_POST['email'];
                $_SESSION['role']   = $rows[0]['role'];
                $_SESSION['name']   = $rows[0]['name'];
                //Сбрасываем параметры
                header('Location:'. BEZ_HOST .'?mode=auth');
                exit;
            }
            else
                echo showErrorMessage('Неверный пароль!');
        }else{
            echo showErrorMessage('Логин <b>'. $_POST['email'] .'</b> не найден!');
        }
    }
 }
?>
  
Остается поправить файл вывода контента ./scripts/auth/show.php заменяем его содержимое на вот это:
  
<?php
 /**
 * Скрипт распределения ресурсов
 * Site: http://bezramok-tlt.ru
 * Проверяем права на чтение данных,
 * только для зарегистрированных пользователей
 */
 //Проверяем зашел ли пользователь
 if($user === false){
    echo '<h3>Привет Гость, доступ закрыт авторизируйтесь!</h3>'."\n";
 }
 
 //Если пользователь авторизовался
 if($user === true) {
    //Пишем приветствие
    echo '<h4>Добро пожаловать <span style="color:red;">'. $_SESSION['login'] .'
    </span> - вы вошли как <span style="color:red;">'.$_SESSION['name'].'
    </span> <a href="'.BEZ_HOST.'?mode=auth&exit=true">ВЫЙТИ</a></h4>';
    
    //Запрос на выборку контента согласно роли
    $sql = 'SELECT * FROM `'. BEZ_DBPREFIX.'content`
            WHERE `role` LIKE "%'. $_SESSION['role'] .'%"';
    $stmt = $db->prepare($sql);
    
    //Выводим контент
    if($stmt->execute()){
        
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach($rows as $val){
            echo '# - <strong>'. $val['id'] .'</strong><br/>';
            echo $val['content'] .'<br/><br/>';
        }
    }
 }
 ?>
  
                        
                     
                08/12/2022 19:55:13
 
                         
                        Письмо отсылается на ящик пользователя при регистрации. Более подробней тут https://bezramok-tlt.ru/blog/posts/registraciya-i-avtorizaciya-na-php-mysql
12/12/2022 13:12:47
 
                25/07/2022 22:19:04
 
                26/10/2017 14:16:35
 
                         
                        Можно и так. Как я Вам писал ранее я бы использовал ID_ROLE для идентификации роли, а так же рекомендовал после перенаправления использовать полный путь до скрипта и явную остановку скрипта.
Пример:
header('Location: http://site/admin.php');
exit;
По поводу благодарности, если есть желание и средства можете закинуть мне на ЯндексКошелек 41001421295778 ))
26/10/2017 20:44:57
 
                17/10/2017 21:11:10
 
                         
                        Только сейчас пришло уведомление о вашем вопросе.
Для того чтобы реализовать вашу задумку нужно оперировать данными из таблицы с ролями (BEZ_ROLE) , а именно использовать поле ID_ROLE так как это целочисленный параметр и с ним легче работать чем со строкой.
Далее делаете проверку кто и с какой ролью находится сейчас на странице и исходя из ситуации применять те или иные действия согласно вашим правилам для конкретной роли пользователя.
26/10/2017 20:37:50
 
                31/05/2017 09:17:22
 
                30/05/2017 13:54:38
 
                         
                        Ошибки говорят о том, что переменная не определена. Так как это сессионые переменные, они хранятся на сервере до закрытия браузера. Устанавливаются эти переменные в \scripts\auth\auth.php c 58 по 61 строчку.
Должно быть:
//Переменные для работы с залогиненым пользователем! $_SESSION['user'] = true; $_SESSION['login'] = $_POST['email']; $_SESSION['role'] = $rows[0]['role']; $_SESSION['name'] = $rows[0]['name'];
30/05/2017 14:44:57
 
                29/05/2017 16:21:38
 
                         
                        Найдите файл ./scripts/reg/reg.php в нем найдите строки где происходит запись данных в БД. Скорей всего, когда вы добавляете поле role в таблицу при этом в запросе при регистрации отсутствует параметр по умолчанию для данного поля.
Замените запрос на:
$sql = 'INSERT INTO `'. BEZ_DBPREFIX .'reg`
		VALUES(
				"",
				:email,
				:pass,
				:salt,
				"'. md5($salt) .'",
				0,
				3
				)';
//Подготавливаем PDO выражение для SQL запроса
$stmt = $db->prepare($sql);
$stmt->bindValue(':email', $_POST['email'], PDO::PARAM_STR);
$stmt->bindValue(':pass', $pass, PDO::PARAM_STR);
$stmt->bindValue(':salt', $salt, PDO::PARAM_STR);
$stmt->execute();
                            29/05/2017 20:08:19
 
                29/05/2017 14:54:47
 
                         
                        Сложно сказать, так как нет ни каких данных по и изменению таблиц и скриптов. Пришлите скриншоты с ошибками и структурой БД мне на почту bezramok-tlt@mail.ru
29/05/2017 15:29:32
 
                07/02/2017 16:56:14
 
                         
                        Попробуйте так:
<?php
/* Connect to a MySQL database using driver invocation */
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES cp1251',
                 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);
try {
    $dbh = new PDO($dsn, $user, $password, $options);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}
?> 
                            07/02/2017 18:00:19
 
                02/02/2017 16:04:30