#10 php Простейшая авторизация: форма входа, пароль и $_SESSION
Primary tabs
Пора собрать всё вместе: формы, сессии и редиректы дадут нам полноценную (пусть и крошечную) авторизацию. Сделаем страницу входа с логином и паролем — и «секретную» страницу, которую видно только вошедшим. Так работают входы на всех сайтах, различие лишь в том, где хранится список пользователей.
Немного теории
Основа — сессии: после успешной проверки мы запишем в $_SESSION факт «этот посетитель вошёл как admin», и все страницы сайта смогут это проверить. Поле для пароля описано в учебнике: поле для ввода пароля — оно такое же текстовое, но символы не показываются. Альтернативный, «древний» способ узнавать пользователя — HTTP-аутентификация — упомянем для кругозора: сегодня для входа на сайте почти всегда используют именно сессии.
Всё остальное нам уже знакомо: самопроверка формы из урока про отправку формы и редиректы из урока про обработчик.
Файл первый: страница входа
Логин и пароль для простоты зашиты в код: admin / 12345.
<?php
session_start();
// уже вошли? - сразу на закрытую страницу
if (isset($_SESSION['user'])) {
header('Location: secret.php');
exit;
}
$login = '';
$password = '';
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['login'])) {
$login = $_POST['login'];
}
if (isset($_POST['password'])) {
$password = $_POST['password'];
}
if ($login === 'admin' && $password === '12345') {
$_SESSION['user'] = $login;
header('Location: secret.php');
exit;
}
$error = 'Неверный логин или пароль.';
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Вход</title>
</head>
<body>
<h1>Вход</h1>
<?php if ($error !== '') { ?>
<p><?php echo htmlspecialchars($error); ?></p>
<?php } ?>
<form action="" method="post">
<p>Логин:
<input type="text" name="login"
value="<?php echo htmlspecialchars($login); ?>">
</p>
<p>Пароль:
<input type="password" name="password">
</p>
<p><button type="submit">Войти</button></p>
</form>
</body>
</html>
Что здесь происходит:
- если посетитель уже вошёл (в сессии есть
user) — форма входа ему не нужна, отправляем его сразу на закрытую страницу; - форма обрабатывает сама себя: это знакомый приём с проверкой REQUEST_METHOD;
- при совпадении логина и пароля пишем в сессию
$_SESSION['user']— с этого момента все страницы сайта «знают», что посетитель вошёл; - после успеха — редирект (тот же приём, что в уроке про форму и обработчик), а при неудаче — сообщение и форма с сохранённым логином.
Файл второй: закрытая страница
secret.php — «только для своих»:
<?php
session_start();
// не вошёл? - на страницу входа
if (!isset($_SESSION['user'])) {
header('Location: login.php');
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Секретная страница</title>
</head>
<body>
<h1>Только для своих</h1>
<p>Привет, <?php echo htmlspecialchars($_SESSION['user']); ?>!</p>
<p>Здесь мог бы быть ваш личный кабинет.</p>
</body>
</html>
Вся «охрана» — три строки в начале: нет в сессии user — значит, не входил, и страница сама отправляет на форму входа. Этот блок-«страж» ставят в начало каждой закрытой страницы сайта.
Прогоняем сценарий
- откройте
http://localhost:19791/lessons/lesson10-auth/secret.phpне входя — вас перебросит наlogin.php; - введите неверный пароль — появится «Неверный логин или пароль», логин останется в поле;
- введите
admin/12345— попадёте на закрытую страницу: «Привет, admin!»; - откройте
secret.phpещё раз — пускает без формы: сервер узнаёт вас по кукеPHPSESSID(урок про сессии); - а теперь откройте закрытую страницу в режиме инкогнито — снова на вход: у того браузера своя, пустая сессия.
Честное замечание про пароли
Пара «admin/12345», зашитая в код, — приём только для учёбы. В реальных системах пользователи лежат в базе, пароли хранят в виде хэшей (для этого в PHP есть функции password_hash() и password_verify()), а сам вход обслуживается по HTTPS. И заметьте нашу фразу ошибки: «Неверный логин или пароль» — без уточнения, что именно неверно: так злоумышленнику сложнее понять, существует ли логин.
Попробуйте сами
- поменяйте логин и пароль в коде и проверьте оба сценария ещё раз;
- сделайте «вторую секретную страницу» (например,
secret2.php) с тем же стражем — вход один, закрытых страниц сколько угодно; - посложнее: добавьте на страницу входа сообщение «Вы уже вошли» для тех, кто попал туда с живой сессией (подсказка: перед редиректом можно добавить GET-параметр — так мы передавали флаг sent в уроке про форму и обработчик).
Итоги
- факт входа хранят в сессии:
$_SESSION['user']; - каждая закрытая страница начинается со «стража»: нет метки — редирект на вход;
- форма входа обрабатывает себя сама и после успеха делает редирект;
- реальные пароли хранят хэшами, а не открытым текстом.
В следующем уроке доделаем картину: сделаем «выход» — очистим сессию в отдельном logout.php.
- Log in to post comments
- 10 reads