Уважаемые друзья, форма вопрос - ответ снова в строю!

Создание ролей пользователей на сайте

Роли пользователей

Привет друзья. Хочу поговорить с вами о методе разграничения прав пользователей на сайте, а точнее о ролях пользователей.

Роль пользователя – это совокупность прав и разрешений выданные той или иной роли описанной в информационной системе.

Так вот, на любом форуме вы встречали администраторов, модераторов, гостей и т.д. Все это и есть роли. Каждая из ролей отвечает своим задачам и имеет свои привилегии. В Web приложениях роли создаются программистом, он сам создает роли и описывает их права.

Самые распространённые роли это:

  • Администратор
  • Модератор
  • Пользователь
  • Гость

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

Переходя от слов к делу нам понадобится - Регистрация пользователей PHP MySQL с активацией письмом. Данный скрипт в версии с PDO мы будем модернизировать для создания авторизации с ролью пользователя. Мы немного модернизируем нашу табличку где у нас хранятся пользователи. Создадим еще две таблички – это таблица ролей пользователей и таблица с контентом.

И так, создадим таблицы в нашей базе данных. У меня это таблицы:

  • Bez_reg
  • Bez_role
  • Bez_content

В таблице bez_reg в конце добавляем поле role, где собственно и будет привязка пользователя к роли.

Таблица bez_reg

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

Далее создаем таблицу bez_role, где напишим названия наших ролей:

  • Администратор
  • Модератор
  • Пользователь
Таблица 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_role

Данный трех ролей нам будет достаточно, чтобы система ролей работала. Создаем третью таблицу bez_contnet, здесь будет храниться контент и роли пользователей которым можно просматривать данный контент.

Таблица bez_content

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

Таблица bez_contnet

С таблицами разобрались, теперь нужно нам сделать себя администраторами т.к. по идее при импорте базы данных у вас должна быть учетная запись по умолчанию с ролью администратор, но так как мы делаем все сами, то нам не лень залезть в базу и сделать себя админом )).

Регистрируемся через форму регистрации, активируем свой аккаунт изменив поле status = 1 и делаем себя администратором установив в поле role = 1.

Таблица bez_reg

Далее заполняете таблицу 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 должен быть таким:

Файл auth.php

<?php
 /**
 * Обработчик формы авторизации
 * Site: http://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 заменяем его содержимое на вот это:

Файл 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/>';
		}
	}
 }
 ?>
ub3gad
14:16:35 26/10/2017г.
lilu, мой костыль по поводу перехода на ту или иную страницу в зависимости от прав пользователя, не уверен что сделал все грамотно, так как  php изучаю третий день...

код моего show.php



    $name = $_SESSION['name'];

 //Проверяем зашел ли пользователь

 if($user === false) {

    echo '<h3>Доступ закрыт, Вы не вошли в систему!</h3>'."\n";

 }

 if($user === true) {

     //    echo "$name";

   switch($name)

   {

      case 'Пользователь':

         header ('Location: user.php'); 

      break;

      

      case 'Администратор':

         header ('Location: admin.php'); 

      break;



  

  }  

}

 ?>

Большое спасибо автору этого ресурса за материал, если есть электронный кошелек(не нашел на сайте), перекину немного денег на бокал пива/сока))   

Можно и так. Как я Вам писал ранее я бы использовал ID_ROLE для идентификации роли, а так же рекомендовал после перенаправления использовать полный путь до скрипта и явную остановку скрипта.


Пример:


header('Location: http://site/admin.php');


exit; 


 


По поводу благодарности, если есть желание и средства можете закинуть мне на ЯндексКошелек   41001421295778  ))

- Администрация     - 20:44:57 26/10/2017г.

Lilu
21:11:10 17/10/2017г.
Доброго времени суток. Подскажите пожалуйста, что необходимо прописать в файле show.php, чтобы админ при входе сразу попадал на определенную страницу (админку), например такую - http://primer:8080/admin/, а для остальных пользователей открывалась главная (или определенная) страница с указанием логина в нижнем правом углу. Спасибо.

Только сейчас пришло уведомление о вашем вопросе. 


Для того чтобы реализовать вашу задумку нужно оперировать данными из таблицы с ролями (BEZ_ROLE) , а именно использовать поле ID_ROLE так как это целочисленный параметр и с ним легче работать чем со строкой.


Далее делаете проверку кто и с какой ролью находится сейчас на странице и исходя из ситуации применять те или иные действия согласно вашим правилам для конкретной роли пользователя.

- Администрация     - 20:37:50 26/10/2017г.

NikitaR
09:17:22 31/05/2017г.
Все так же написано, проблема в том, на сколько я понял, что вход в сайт происходит из за нажатия на зарегистрироваться в разделе регистрации новых юзеров, а в auth  переменные которые проверяются и выводятся остаются пустыми, что подскажите 

Как я вам писал ранее, ошибка в отсутствии переменной. Что-то у вас с сессиями происходит. Скачайте скрипт заново с этого раздела и попробуйте его. 

- Администрация     - 20:02:19 31/05/2017г.

NikitaR
13:54:38 30/05/2017г.
Если после регистрации пользователя (после ввода мыла, паролей и нажатия на кнопку зарегистрироваться) перейти в войти, то под полями ввода выскакивает такое:

Notice: Undefined index: login in .\scripts\auth\show.php on line 15

Notice: Undefined index: name in .\scripts\auth\show.php on line 16

Добро пожаловать - вы вошли как ВЫЙТИ

Notice: Undefined index: role in .\scripts\auth\show.php on line 21

# - 1

# - 2

# - 3

При неудачной попытке регистрации такого не происходит.

Файл show.php не изменял и не лез в него.

Ошибки говорят о том, что переменная не определена. Так как это сессионые переменные, они хранятся на сервере до закрытия браузера. Устанавливаются эти переменные в \scripts\auth\auth.php c 58 по 61 строчку.


Должно быть:


	
//Переменные для работы с залогиненым пользователем!
$_SESSION['user'] = true;
$_SESSION['login'] = $_POST['email'];
$_SESSION['role'] = $rows[0]['role'];
$_SESSION['name'] = $rows[0]['name'];

- Администрация     - 14:44:57 30/05/2017г.

Nik_ki4
16:21:38 29/05/2017г.
Админ, я ничего не изменял в вашем же проекте РЕГИСТРАЦИЯ И АВТОРИЗАЦИЯ НА PHP + MYSQL, единственное изменение это добавил кнопку, но она не вносит изменений в работу бд, к слову, если удалить из таблицы столб role в bez_reg юзеры снова добавляются 

CREATE TABLE `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 DEFAULT '3',

   PRIMARY KEY (`id`)

)

COLLATE='utf8_general_ci'

ENGINE=MyISAM

AUTO_INCREMENT=16

;

Найдите  файл ./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();

- Администрация     - 20:08:19 29/05/2017г.

Nik_ki4
14:54:47 29/05/2017г.
Здравствуйте, возникла проблема, после добавления ролей в основную таблицу, при регистрации, перестали добавляться новые пользователи, как это исправить?

Сложно сказать, так как нет ни каких данных по и изменению таблиц и скриптов. Пришлите скриншоты с ошибками и структурой БД мне на почту bezramok-tlt@mail.ru

- Администрация     - 15:29:32 29/05/2017г.

Получить уведомление на Email

Введите код с картинки