Авторизация и аутентификация в PHP: от основ до безопасности
В современной веб-разработке аутентификация (проверка подлинности пользователя) и авторизация (проверка прав доступа) являются фундаментальными механизмами безопасности. На PHP эти процессы реализуются через работу с сессиями, куками, хешированием паролей и токенами. В этой статье мы разберём все ключевые аспекты, необходимые для создания безопасной системы входа на образовательном сайте pythonlib.ru.
1. Основные понятия: аутентификация vs авторизация
Прежде чем писать код, важно чётко различать два термина:
- Аутентификация — процесс проверки, что пользователь является тем, за кого себя выдаёт (логин + пароль, биометрия, токен).
- Авторизация — определение, какие ресурсы и действия доступны аутентифицированному пользователю (роли: админ, модератор, пользователь).
В PHP аутентификация обычно выполняется через сессии или JWT, а авторизация — через проверку ролей в базе данных.
2. Хеширование паролей: никогда не храните пароли в открытом виде
PHP предоставляет встроенные функции для безопасного хеширования паролей. Используйте password_hash() и password_verify() — это современный стандарт.
// Регистрация пользователя
$password = $_POST['password'];
$hashedPassword = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
// Сохраняем $hashedPassword в БД
$sql = "INSERT INTO users (email, password_hash) VALUES (?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$_POST['email'], $hashedPassword]);
// Проверка при входе
$inputPassword = $_POST['password'];
$storedHash = $user['password_hash']; // из БД
if (password_verify($inputPassword, $storedHash)) {
// Аутентификация успешна
$_SESSION['user_id'] = $user['id'];
} else {
// Неверный пароль
}
3. Управление сессиями в PHP
Сессии — самый распространённый способ отслеживания аутентифицированных пользователей. PHP автоматически генерирует уникальный идентификатор сессии и сохраняет его в куке.
// Начало сессии (всегда в начале скрипта)
session_start();
// После успешного входа
$_SESSION['user_id'] = $user['id'];
$_SESSION['user_role'] = $user['role']; // для авторизации
$_SESSION['logged_in'] = true;
// Проверка аутентификации на защищённых страницах
function requireAuth() {
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
header('Location: /login.php');
exit;
}
}
// Выход из системы
session_destroy();
setcookie(session_name(), '', time() - 3600, '/');
4. Безопасность сессий: защита от атак
Для предотвращения перехвата сессий (Session Hijacking) и фиксации сессий (Session Fixation) используйте следующие меры:
- Регенерация ID сессии после входа:
session_regenerate_id(true); // удаляет старую сессию
- Проверка User-Agent и IP (необязательно, но повышает безопасность):
$_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
// При каждом запросе
if ($_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) {
session_destroy();
die('Подозрительная активность');
}
- Установка флагов для куки сессии в
php.iniили черезsession_set_cookie_params():
session_set_cookie_params([
'lifetime' => 0, // до закрытия браузера
'secure' => true, // только HTTPS
'httponly' => true, // недоступна из JavaScript
'samesite' => 'Strict' // защита от CSRF
]);
session_start();
5. JWT (JSON Web Tokens) для API и бессерверных приложений
Если вы разрабатываете REST API или хотите избежать хранения состояния на сервере, используйте JWT. В PHP популярна библиотека firebase/php-jwt.
// Установка через Composer
// composer require firebase/php-jwt
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
$secretKey = 'ваш-секретный-ключ-не-менее-32-символов';
// Создание токена при входе
$payload = [