КаталогBuilderPHPDocs

Глава 9. Сессии, cookies и авторизация в PHP

Сессии и cookies позволяют сайту запоминать пользователя между запросами. Без них невозможны личные кабинеты, корзины, авторизация, настройки интерфейса и админ-панели. Но именно в этой теме важно понимать разницу между удобством и безопасностью.

Современное примечание. В старых скриптах часто хранили в cookie логин и пароль или простой md5-хеш. Так делать нельзя. Cookie должны хранить только безопасные идентификаторы или токены, а пароли — только в виде современных хешей.

Что такое сессия

Сессия хранит данные на сервере, а в браузер отправляется только идентификатор сессии. В PHP работа начинается с session_start(). Его нужно вызвать до вывода HTML.

session_start();

$_SESSION['user_id'] = 15;
$_SESSION['role'] = 'admin';

Чтение данных сессии

После запуска сессии данные доступны через массив $_SESSION. Перед использованием ключ лучше проверять.

if (!empty($_SESSION['user_id'])) {
    echo 'Пользователь авторизован';
}

Что такое cookies

Cookie хранятся в браузере пользователя. Их удобно использовать для неопасных настроек: тема сайта, язык, согласие с уведомлением. Для авторизации cookie должны применяться осторожно.

setcookie('theme', 'dark', time() + 3600 * 24 * 30, '/', '', true, true);

Последние параметры важны: secure ограничивает cookie HTTPS-соединением, httponly запрещает доступ из JavaScript.

Простая схема авторизации

Авторизация обычно состоит из четырёх этапов: пользователь отправляет логин и пароль, сервер ищет пользователя в базе, проверяет пароль, затем записывает ID пользователя в сессию.

if (password_verify($password, $user['password_hash'])) {
    session_regenerate_id(true);
    $_SESSION['user_id'] = $user['id'];
}

Хранение паролей

Пароли нельзя хранить открытым текстом. Нельзя использовать md5 или sha1. В современном PHP применяются password_hash() и password_verify().

$hash = password_hash($password, PASSWORD_DEFAULT);

if (password_verify($password, $hash)) {
    echo 'Пароль верный';
}

Выход пользователя

При выходе нужно удалить данные сессии и завершить её. Для критичных систем также стоит сбросить cookie идентификатора сессии.

session_start();
$_SESSION = [];
session_destroy();

Запомнить меня

Функция «запомнить меня» не должна хранить пароль в cookie. Безопаснее использовать пару selector/token: selector помогает найти запись, token хранится в базе в виде хеша и проверяется при входе.

Безопасность сессий

  • После входа вызывайте session_regenerate_id(true).
  • Не храните в сессии лишние персональные данные.
  • Используйте HTTPS.
  • Для административных действий проверяйте права доступа.
  • Для важных форм используйте CSRF-токены.

Типичные ошибки

  • Хранить пароль или md5 пароля в cookie.
  • Не обновлять ID сессии после входа.
  • Проверять только факт авторизации, но не роль пользователя.
  • Считать cookie надёжным источником данных.

Итоги

Сессии подходят для хранения состояния пользователя на сервере, cookies — для передачи небольших данных между браузером и сайтом. Для авторизации важны правильное хеширование паролей, обновление ID сессии, HTTPS, проверка прав и аккуратная реализация функции «запомнить меня».