Php mysql таблица пользователей

Безопасный метод авторизации на PHP

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

Модель авторизации:

Клиент
Сервер MySQL

Таблица users
user_id (int(11))
user_login (Varchar(30))
user_password (varchar(32))
user_hash (varchar(32))
user_ip (int(10)) по умолчанию 0

При регистрации в базу данных записывается логин пользователя и пароль(в двойном md5 шифровании).

При авторизации сравнивается логин и пароль, если они верны, то генерируется случайная строка, которая хешируется и добавляется в БД в строку user_hash. Также записывается IP-адрес пользователя (но это у нас будет опциональным, так как кто-то сидит через Proxy, а у кого-то IP динамический. тут уже пользователь сам будет выбирать безопасность или удобство). В куки пользователя мы записываем его уникальный индетификатор и сгенерированный hash.

Почему надо хранить в куках хеш случайно сгенерированной строки, а не хеш пароля?

  1. Из-за невнимательности программиста во всей системе могут быть дырки, воспользовавшись этими дырками, злоумышленик может вытащить хеш пароля из БД и подставить его в свои куки, тем самым получить доступ к закрытым данным. В нашем же случае двойной хеш пароля ничем не сможет помочь хакеру, так как расшифровать его он не сможет (теоретически это возможно, но на это он потратит не один месяц, а может быть, и год), а воспользоваться этим хешем ему негде, ведь у нас при авторизации свой уникальный хеш прикрепленный к IP пользователя.
  2. Если злоумышленик вытащит трояном у пользователя уникальный хеш, воспользоваться им он также не сможет (разве, если только пользователь решил пренебречь своей безопастностью и выключил привязку к IP при авторизации).
Читайте также:  Пятеричная система счисления питон

Реализация

Структура таблицы `users` в базе данных ‘testtable’
CREATE TABLE `users` ( `user_id` int(11) unsigned NOT NULL auto_increment, `user_login` varchar(30) NOT NULL, `user_password` varchar(32) NOT NULL, `user_hash` varchar(32) NOT NULL default '', `user_ip` int(10) unsigned NOT NULL default '0', PRIMARY KEY (`user_id`) ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1 ;

register.php

if(strlen($_POST[‘login’]) < 3 or strlen($_POST['login']) >30) < $err[] = "Логин должен быть не меньше 3-х символов и не больше 30"; >// проверяем, не сущестует ли пользователя с таким именем $query = mysqli_query($link, «SELECT user_id FROM users WHERE user_login='».mysqli_real_escape_string($link, $_POST[‘login’]).»‘»); if(mysqli_num_rows($query) > 0) < $err[] = "Пользователь с таким логином уже существует в базе данных"; >// Если нет ошибок, то добавляем в БД нового пользователя if(count($err) == 0) < $login = $_POST['login']; // Убераем лишние пробелы и делаем двойное хеширование $password = md5(md5(trim($_POST['password']))); mysqli_query($link,"INSERT INTO users SET user_login='".$login."', user_password='".$password."'"); header("Location: login.php"); exit(); >else < print "При регистрации произошли следующие ошибки:
«; foreach($err AS $error) < print $error."
«; > > > ?> Логин
Пароль
return $code; > // Соединямся с БД $link=mysqli_connect(«localhost», «mysql_user», «mysql_password», «testtable»); if(isset($_POST[‘submit’])) < // Вытаскиваем из БД запись, у которой логин равняеться введенному $query = mysqli_query($link,"SELECT user_id, user_password FROM users WHERE user_login='".mysqli_real_escape_string($link,$_POST['login'])."' LIMIT 1"); $data = mysqli_fetch_assoc($query); // Сравниваем пароли if($data['user_password'] === md5(md5($_POST['password']))) < // Генерируем случайное число и шифруем его $hash = md5(generateCode(10)); if(!empty($_POST['not_attach_ip'])) < // Если пользователя выбрал привязку к IP // Переводим IP в строку $insip = ", user_ip=INET_ATON('".$_SERVER['REMOTE_ADDR']."')"; >// Записываем в БД новый хеш авторизации и IP mysqli_query($link, «UPDATE users SET user_hash='».$hash.»‘ «.$insip.» WHERE user_id='».$data[‘user_id’].»‘»); // Ставим куки setcookie(«id», $data[‘user_id’], time()+60*60*24*30, «/»); setcookie(«hash», $hash, time()+60*60*24*30, «/», null, null, true); // httponly . // Переадресовываем браузер на страницу проверки нашего скрипта header(«Location: check.php»); exit(); > else < print "Вы ввели неправильный логин/пароль"; >> ?> Логин
Пароль
Не прикреплять к IP (небезопасно)
Логин
Пароль
Не прикреплять к IP(не безопасно)

Читайте также:  Python timedelta get hours

Для защиты формы логина от перебора, можно использовать капчу или временную задержку на повторную авторизацию.

Автор: http://jiexaspb.habrahabr.ru/. Адаптация под PHP 5.5 и MySQL 5.7 KDG.

Куки с флагом HttpOnly не видны браузерному javascript-коду, а отправляются только на сервер. На практике у вас никогда не будет необходимости получать их содержимое в javascript. А вот злоумышленнику, нашедшему XSS – а XSS так или иначе когда-нибудь где-нибудь найдется – отсутствие HttpOnly на авторизационных куках доставит много радости.

Другие примеры авторизации на PHP:

Источник

Php mysql таблица пользователей

Для выполнения запросов у объекта mysqli вызывается метод query() , в который передается выполняемая команда SQL:

$conn = new mysqli("localhost", "root", "mypassword"); $conn->query(команда_sql);

Если выполнение запроса прошло успешно, то метод query() возвращает true , если неудачно, то возвращается false .

Процедурный подход

При процедурном подходе для выполнения вызывается функция mysqli_query() , в которую передается объект подключения и выполняемая команда SQL:

$conn = mysqli_connect("localhost", "root", "mypassword"); mysqli_query($conn, $query);

Если выполнение запроса прошло успешно, то функция mysqli_query() возвращает true , если неудачно, то возвращается false .

Создание базы данных

Для создания базы данных в MySQL применяется команда CREATE DATABASE , после которой указывается имя создаваемой базы данных. Создадим базу данных с помощью PHP.

Объектно-ориентированный подход

connect_error)< die("Ошибка: " . $conn->connect_error); > // Создаем базу данных testdb2 $sql = "CREATE DATABASE testdb2"; if($conn->query($sql)) < echo "База данных успешно создана"; >else< echo "Ошибка: " . $conn->error; > $conn->close(); ?>

Здесь создается база данных testdb2 . Если при выполнении команды возникнет ошибка, то мы можем получить информацию о ней через свойство $conn->error .

Процедурный подход

 // Создаем базу данных testdb3 $sql = "CREATE DATABASE testdb3"; if(mysqli_query($conn, $sql)) < echo "База данных успешно создана"; >else < echo "Ошибка: " . mysqli_error($conn); >mysqli_close($conn); ?>

Здесь создается база данных testdb3 . Если при выполнении команды возникнет ошибка, то мы можем получить информацию о ней через функцию mysqli_error() , в которую передается объект подключения.

Создание таблицы

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

CREATE TABLE Users (id INTEGER AUTO_INCREMENT PRIMARY KEY, name VARCHAR(30), age INTEGER);

Здесь создается таблица под названием «users». Она будет хранить условных пользователей. В ней будет три столбца: id, name и age. Столбец id представляет числовой уникальный идентификатор строки — или идентификатор пользователя. Столбец name представляет строку — имя пользователя. А столбец age хранит число — возраст пользователя.

Объектно-ориентированный подход

connect_error)< die("Ошибка: " . $conn->connect_error); > $sql = "CREATE TABLE Users (id INTEGER AUTO_INCREMENT PRIMARY KEY, name VARCHAR(30), age INTEGER);"; if($conn->query($sql)) < echo "Таблица Users успешно создана"; >else< echo "Ошибка: " . $conn->error; > $conn->close(); ?>

Если мы обращаемся уже непосредственно к базе данных, то ее имя передается в качетстве четвертого параметра в конструктор mysqli : new mysqli(«localhost», «root», «mypassword», «testdb2»); .

Процедурный подход

 $sql = "CREATE TABLE Users (id INTEGER AUTO_INCREMENT PRIMARY KEY, name VARCHAR(30), age INTEGER);"; if(mysqli_query($conn, $sql)) < echo "Таблица Users успешно создана"; >else < echo "Ошибка: " . mysqli_error($conn); >mysqli_close($conn); ?>

Если мы подключаемся к конкретной базе данных, то ее имя передается в качетстве четвертого параметра в функцию mysqli_connect() : mysqli_connect(«localhost», «root», «mypassword», «testdb3») .

Источник

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

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

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

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

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

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

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

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

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

В таблице 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_reg

Далее создаем таблицу 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 , здесь будет храниться контент и роли пользователей которым можно просматривать данный контент.

 -- -- 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 должен быть таким:

  //Если нажата кнопка то обрабатываем данные 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('Логин '. $_POST['email'] .' не найден!'); > > > ?> 

Остается поправить файл вывода контента ./scripts/auth/show.php заменяем его содержимое на вот это:

 Привет Гость, доступ закрыт авторизируйтесь!'."\n"; > //Если пользователь авторизовался if($user === true) < //Пишем приветствие echo '

Добро пожаловать '. $_SESSION['login'] .' - вы вошли как '.$_SESSION['name'].' ВЫЙТИ

'; //Запрос на выборку контента согласно роли $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 '# - '. $val['id'] .'
'; echo $val['content'] .'

'; > > > ?>

Источник

Оцените статью