Авторизация и аутентификация в PHP: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Авторизация и аутентификация в PHP: от основ до защиты

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

1. Основные понятия: аутентификация vs авторизация

Прежде чем писать код, важно четко разграничить два термина:

  • Аутентификация — процесс проверки, что пользователь является тем, за кого себя выдает (обычно через логин и пароль).
  • Авторизация — процесс определения, какие ресурсы или действия доступны аутентифицированному пользователю (например, роль "admin" или "user").

Ошибки в реализации любого из этих этапов могут привести к утечке данных или несанкционированному доступу.

2. Базовая аутентификация через сессии (нативный PHP)

Самый распространенный способ — использование сессий. PHP предоставляет встроенный механизм $_SESSION. Рассмотрим простой пример.

Шаг 1: Форма входа (login.php)

<?php
session_start();
?>
<!DOCTYPE html>
<html>
<head>
    <title>Вход на сайт</title>
</head>
<body>
    <form method="POST" action="login.php">
        <label>Логин:</label>
        <input type="text" name="username" required>
        <label>Пароль:</label>
        <input type="password" name="password" required>
        <button type="submit" name="login">Войти</button>
    </form>
</body>
</html>

Шаг 2: Обработка входа (тот же login.php)

<?php
session_start();
require_once 'db.php'; // подключение к БД

if (isset($_POST['login'])) {
    $username = trim($_POST['username']);
    $password = $_POST['password'];

    // 1. Подготовленный запрос для защиты от SQL-инъекций
    $stmt = $pdo->prepare("SELECT id, password_hash FROM users WHERE username = ?");
    $stmt->execute([$username]);
    $user = $stmt->fetch();

    // 2. Проверка пароля через password_verify
    if ($user && password_verify($password, $user['password_hash'])) {
        // Аутентификация успешна
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['logged_in'] = true;
        header("Location: dashboard.php");
        exit;
    } else {
        $error = "Неверный логин или пароль";
    }
}
?>

Шаг 3: Проверка авторизации на защищенной странице

<?php
session_start();
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
    header("Location: login.php");
    exit;
}
// Доступ разрешен
echo "Добро пожаловать, пользователь #" . htmlspecialchars($_SESSION['user_id']);
?>

3. Хеширование паролей: никогда не храните пароли в открытом виде

PHP предоставляет безопасные функции для работы с паролями:

  • password_hash($password, PASSWORD_BCRYPT) — создает хеш с солью автоматически.
  • password_verify($password, $hash) — проверяет пароль против хеша.

Пример регистрации пользователя:

<?php
$password = "user123";
$hash = password_hash($password, PASSWORD_BCRYPT);
// Сохраняем $hash в базу данных
$stmt = $pdo->prepare("INSERT INTO users (username, password_hash) VALUES (?, ?)");
$stmt->execute([$username, $hash]);
?>

Важно: никогда не используйте md5() или sha1() для паролей — они устарели и легко взламываются.

4. Ролевая авторизация (Role-Based Access Control)

Для разграничения прав используйте роли. Добавьте поле role в таблицу пользователей (например, 'admin', 'editor', 'user').

Пример проверки прав доступа:

<?php
session_start();
// Предположим, что роль хранится в сессии при логине
$role = $_SESSION['role'] ?? 'guest';

function isAdmin(): bool {
    return isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
}

if (!is                    

Рекомендаций