Простая авторизация и аутентификация на PHP в связке с MySQL
Все кто разрабатывает web сайты, рано или поздно сталкивается с такой задачей как авторизация и аутентификация пользователей, реализованная именно с помощью языка программирования, а не с помощью стандарта протокола http. Сегодня мы рассмотрим пример создания простой авторизации с использованием языка программирования PHP, а данные о пользователях будем хранить в базе MySQL.
Приведенный ниже способ является простым или как бы основой для создания нормальной авторизации, но его Вы вполне можете использовать, так как он достаточно хорошо работает, также Вы сами можете улучшить этот способ и внедрить у себя на сайте.
Данный способ основан на сессиях, но я здесь применяю и куки, для того чтобы браузер запоминал пользователя, который аутентифицировался прошлый раз, чтобы каждый раз не вводить логин, можно конечно хранить в куках и пароль, но это не безопасно, даже если он зашифрован. Для того чтобы сессия закончилась, просто закройте браузер и откройте заново.
Создание объектов в базе данных
Переходим к практике. Для начала создадим таблицу хранения данных о пользователях в базе MySQL. Я предлагаю использовать простую структуру таблицы (Вы ее, конечно, можете дополнить чем-нибудь, у меня база называется test, а таблица users):
CREATE TABLE test.users( user_id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, user_login VARCHAR(30) NOT NULL, user_password VARCHAR(32) NOT NULL, PRIMARY KEY (user_id) ) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
И давайте сразу же добавим одну запись в эту таблицу:
insert into test.users (user_login, user_password) values ('mylogin','202cb962ac59075b964b07152d234b70')
- Логин – mylogin;
- Пароль — 202cb962ac59075b964b07152d234b70;
Мы пароль, конечно же, будем хранить в хешированном виде, так как хранить пароль в открытом виде, мягко сказать, не безопасно. У нас Выше хеш пароля 123, поэтому, когда будем вводить пароль в форму, мы будем забивать именно 123, а не 202cb962ac59075b964b07152d234b70.
Создание формы регистрации
Для того чтобы пользователь мог сам зарегистрироваться, сделайте форму, данные с которой будут посылаться на файл обработки регистрации, т.е. записываться в базу данных. Например, вот самый простой способ:
0) < $error = "Пользователь с таким логином уже есть"; >// Если нет, то добавляем нового пользователя if(!isset($error) ) < $login = mysql_real_escape_string(trim(htmlspecialchars($_POST['login']))); // Убираем пробелы и хешируем пароль $password = md5(trim($_POST['password'])); mysql_query("INSERT INTO users SET user_login='".$login."', user_password='".$password."'"); echo 'Вы успешно зарегистрировались с логином - '.$login; exit(); >else < // если есть такой логин, то говорим об этом echo $error; >> //по умолчанию данные будут отправляться на этот же файл print Логин
Пароль
html; ?>
Кстати, при таком способе лучше всего для логина использовать латинские буквы (т.е. английские), если хотите писать логин на русском, то придется немного корректировать код. Файл можете назвать как угодно (для теста я использовал reg.html).
Примечание! Для тестирования я использую всего один файл, я его назвал mylogin.html (код файла ниже). Вы можете использовать в своих файлах и называть их как угодно, я здесь описываю сам процесс авторизации, поэтому применить его можно везде. Кстати, во всех файлах придется использовать функцию session_start(); для того чтобы Вы могли проверять авторизован пользователь или нет. И еще один момент, конечно же, пропишите свои настройки подключения к базе данных.
Создание формы авторизации
Теперь перейдем непосредственно к самой авторизации. Создайте файл с названием mylogin.html со следующим содержанием:
else < //если пользователя нет, то пусть пробует еще header("Location: mylogin.html"); >> //проверяем сессию, если она есть, то значит уже авторизовались if (isset($_SESSION['user_id']))< echo htmlspecialchars($_SESSION['user_login'])."
"."Вы авторизованы
Т.е. мы проверили сессию и можем открыть доступ к определенным данным"; > else < $login = ''; //проверяем куку, может он уже заходил сюда if (isset($_COOKIE['CookieMy']))< $login = htmlspecialchars($_COOKIE['CookieMy']); >//простая формочка print Логин
Пароль
html; > ?>
Примечание! Если вдруг у Вас отказывает работать парсер php, т.е. на экран Вам выводится сам код php, то у Вас просто на всего не включена обработка php в файлах html. Настройки делаются в файле конфигурации web сервера httpd.conf (если apache):
AddType application/x-httpd-php .php .html
В IIS в окне «Добавление сопоставления модуля» (Add Module Mapping) добавьте к *.php еще и *.html через запятую. Это если Вы делаете у себя дома на своем web сервере, а если Вы все это делаете у хостера, то Вам придется писать им и просить внести необходимые изменения, у некоторых хостеров они уже сделаны.
Код я прокомментировал, поэтому я думаю, что все должно быть понятно. Еще раз напоминаю во всех файлах, содержимое которых Вы не хотите показывать не авторизованным пользователям, необходимо писать session_start, ну и, наверное, на этом все. Если есть вопросы, задавайте в комментариях. Удачи!
Простая аутентификация на PHP
Многие новички до сих пор попадают в тупик при написании простейшей аутентификации в PHP. На Тостере с завидной регулярностью попадаются вопросы о том, как сравнить сохраненный пароль с паролем полученным из формы логина. Здесь будет краткая статья-туториал на эту тему.
Disclaimer: статья рассчитана на совершенных новичков. Умудрённые опытом разработчики ничего нового здесь не найдут, но могут указать на возможные недочёты =).
Для написания системы аутентификации будем использовать базу данных MySQL/MariaDB, PHP, PDO, функции для работы с паролями, для построения интерфейса возьмём bootstrap.
Для начала создадим базу. Пусть она называется php-auth-demo. В новой базе создадим таблицу пользователей users :
CREATE TABLE `users` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `username` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, `password` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
Создадим конфиг с данными для подключения к базе.
Имейте ввиду, что в реальном проекте к конфигам не должно быть доступа из браузера, и они не должны быть включены в систему контроля версий, во избежание компрометации учетных данных.
'php-auth-demo', 'db_host' => '127.0.0.1', 'db_user' => 'mysql', 'db_pass' => 'mysql', ];
И сделаем «загрузочный» файл, который будем подключать вначале всех остальных файлов.
В реальных проектах обычно используется автозагрузка необходимых файлов. Но этот момент выходит за рамки статьи, и в демо-примере мы обойдёмся простым подключением.
В «загрузочном» файле мы будем инициализировать сессию и объявим некоторые функции-помощники.
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); > return $pdo; >
Функция pdo() даст нам доступ к объекту PDO в любом месте нашего кода.
Далее нам нужна форма регистрации. Разместим её прямо в файле index.php .
Здесь всё просто: два поля, кнопка и форма, отправляющая запрос на файл do_register.php методом POST. Процесс регистрации пользователя опишем в файле do_register.php .
prepare("SELECT * FROM `users` WHERE `username` = :username"); $stmt->execute(['username' => $_POST['username']]); if ($stmt->rowCount() > 0) < flash('Это имя пользователя уже занято.'); header('Location: /'); // Возврат на форму регистрации die; // Остановка выполнения скрипта >// Добавим пользователя в базу $stmt = pdo()->prepare("INSERT INTO `users` (`username`, `password`) VALUES (:username, :password)"); $stmt->execute([ 'username' => $_POST['username'], 'password' => password_hash($_POST['password'], PASSWORD_DEFAULT), ]); header('Location: login.php');
В самом начале подключим наш «загрузчик».
Потом проверим, не занято ли имя пользователя. Для этого сделаем выборку из таблицы указав в условии полученное из формы имя пользователя. Обратите внимание, для запросов здесь и далее мы будем использовать подготовленные запросы, что обезопасит нас от SQL-инъекций. Для этого в тексте SQL-запроса мы указываем специальные плейсхолдеры, а при выполнении ассоциируем с ними ненадёжные данные (ненадёжными данными следует считать всё, что приходит из вне – $_GET, $_POST, $_REQUEST, $_COOKIE). После выполнения запроса мы просто проверим количество возвращённых строк. Если их больше нуля, то имя пользователя уже занято. В этом случае мы выведем сообщение и вернём пользователя на форму регистрации.
Я написал «больше нуля», но по факту, из-за того, что поле username в таблице уникальное, rowCount() может нам вернуть лишь два возможных значения: 0 и 1 .
В приведённом выше коде мы использовали функцию flash() . Данная функция предназначена для «одноразовых» сообщений. Если вызвать её со строковым параметром, то она сохранит эту строку в сессии, а если вызвать без параметров, то выведет из сессии сохранённое сообщение и затем удалит его в сессии. Добавим эту функцию в файл boot.php .
function flash(?string $message = null) < if ($message) < $_SESSION['flash'] = $message; >else < if (!empty($_SESSION['flash'])) < ?> unset($_SESSION['flash']); > >
А также вызовем её нa форме регистрации, для вывода возможных сообщений.
На данном этапе простейший функционал регистрации нового пользователя готов.
Если мы посмотрим код регистрации выше, то увидим, что в случае успешной регистрации, мы перенаправляем пользователя на страницу логина. Самое время ее написать.
Login