Исходный код страницы входа на PHP: от основ до продвинутых техник

Раздел: Веб-разработка -> Аутентификация

Реализация страницы входа на PHP: подходы и примеры

Основной рекомендуемый способ: аутентификация через базу данных с использованием подготовленных запросов и хеширования паролей

Этот подход обеспечивает безопасность, защиту от SQL-инъекций и корректное хранение учётных данных. Сессии позволяют сохранять состояние авторизации.

Как организовать процесс входа с проверкой в MySQL и стартом сессии?


<?php
session_start();
require 'db.php';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $email = trim($_POST['email'] ?? '');
    $password = $_POST['password'] ?? '';

    if (empty($email) || empty($password)) {
        $_SESSION['error'] = 'Заполните все поля.';
        header('Location: login.php');
        exit;
    }

    $stmt = $pdo->prepare('SELECT id, email, password FROM users WHERE email = :email');
    $stmt->execute(['email' => $email]);
    $user = $stmt->fetch();

    if ($user && password_verify($password, $user['password'])) {
        session_regenerate_id(true);
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['email'] = $user['email'];
        header('Location: dashboard.php');
    } else {
        $_SESSION['error'] = 'Неверный email или пароль.';
        header('Location: login.php');
    }
    exit;
}
?>
  

Admin index php login php (страница входа администратора php)

Пояснение: сессия запускается в самом начале. Данные из формы получаются через POST. Подготовленный запрос защищает от инъекций. Пароль проверяется функцией password_verify – пароль должен быть сохранён хешем (например, при регистрации через password_hash). После успешной проверки идентификатор сессии обновляется и сохраняется ID пользователя.

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

  • Забыли вызвать session_start() – сессионные переменные не будут доступны.
  • Использование md5 или sha1 для хранения паролей – они ненадёжны. Следует применять только password_hash и password_verify.
  • Отсутствие проверки на пустые поля – возможна обработка некорректных данных.
  • Передача пароля через GET – пароль будет виден в URL и логах сервера. Используется только POST.

Решение: всегда использовать prepare, проверять метод запроса, очищать вывод ошибок на продакшене, применять session_regenerate_id после входа.

Как сделать простейшую страницу входа без базы данных, с жёстко заданными логином и паролем?

Этот вариант подходит для временных прототипов или очень маленьких проектов, где нет необходимости в масштабировании.


<?php
session_start();
$valid_username = 'admin';
$valid_password_hash = password_hash('secret', PASSWORD_DEFAULT);

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = $_POST['username'] ?? '';
    $password = $_POST['password'] ?? '';
    if ($username === $valid_username && password_verify($password, $valid_password_hash)) {
        $_SESSION['user'] = $username;
        header('Location: admin.php');
    } else {
        $error = 'Неверные учётные данные.';
    }
}
?>
  

Php code login (код страницы входа php)

Проблемы и их решение:

Жёстко прописанные логин и пароль неудобны при смене данных. Кроме того, пароль в исходном коде может быть скомпрометирован. Решение: вынести учётные данные в конфигурационный файл, но всё равно такой подход не рекомендуется для реальных проектов. Лучше использовать базу данных.

Как добавить защиту от CSRF на форме входа?

CSRF-токен предотвращает подделку межсайтовых запросов. Генерация токена и его проверка при отправке формы.


<?php
session_start();
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'] ?? '')) {
        die('Ошибка CSRF-токена');
    }
    // остальная логика входа
}
?>
<form method="post">
    <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
    <!-- остальные поля -->
</form>
  

Request login php (запрос на вход php)

Возможные ошибки:

Если токен не сравнивается через hash_equals, возможно уязвимость timing attack. Используйте именно эту функцию. Также важно регенерировать токен после входа для предотвращения фиксации сессии.

Как интегрировать CAPTCHA (reCAPTCHA v2) в форму входа для защиты от ботов?

Добавление reCAPTCHA снижает риск автоматических атак подбора паролей.


<?php
// server-side verification
$recaptcha_secret = 'ваш_секретный_ключ';
$recaptcha_response = $_POST['g-recaptcha-response'] ?? '';
$verify_url = 'https://www.google.com/recaptcha/api/siteverify';
$data = ['secret' => $recaptcha_secret, 'response' => $recaptcha_response];
$options = ['http' => ['method' => 'POST', 'content' => http_build_query($data)]];
$context = stream_context_create($options);
$result = file_get_contents($verify_url, false, $context);
$response = json_decode($result);
if (!$response->success) {
    $error = 'Пожалуйста, пройдите проверку reCAPTCHA.';
}
?>
  

Проблемы:

Если ключ неверный или на сервере не включено расширение allow_url_fopen, запрос не выполнится. Альтернатива – использовать cURL. Также reCAPTCHA может не срабатывать при использовании локального сервера без SSL в старых версиях.

- Service login php (сервис аутентификации php)
- Login php file (файл входа php)
- Index php id login (авторизация через параметр id в index.php)

Расширенные примеры реализации страницы входа

Пример 1. Полный скрипт входа с PDO, подготовленными запросами и обработкой ошибок

Пример

<?php
session_start();
require_once 'config/database.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('HTTP/1.1 405 Method Not Allowed');
    exit;
}

$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$password = $_POST['password'] ?? '';

if (!$email || empty($password)) {
    $_SESSION['error'] = 'Введите корректный email и пароль.';
    header('Location: login.php');
    exit;
}

try {
    $stmt = $pdo->prepare('SELECT id, email, password, role FROM users WHERE email = :email LIMIT 1');
    $stmt->execute(['email' => $email]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($user && password_verify($password, $user['password'])) {
        session_regenerate_id(true);
        $_SESSION['user'] = [
            'id' => $user['id'],
            'email' => $user['email'],
            'role' => $user['role'],
            'ip' => $_SERVER['REMOTE_ADDR'],
            'logged_at' => time()
        ];
        // запись лога входа
        $logStmt = $pdo->prepare('INSERT INTO login_log (user_id, ip, user_agent) VALUES (:uid, :ip, :ua)');
        $logStmt->execute(['uid' => $user['id'], 'ip' => $_SERVER['REMOTE_ADDR'], 'ua' => $_SERVER['HTTP_USER_AGENT'] ?? '']);

        header('Location: dashboard.php');
        exit;
    } else {
        $_SESSION['error'] = 'Неверный email или пароль.';
        header('Location: login.php');
        exit;
    }
} catch (PDOException $e) {
    // логгируем ошибку, пользователю показываем общее сообщение
    error_log($e->getMessage());
    $_SESSION['error'] = 'Временно недоступно. Повторите попытку позже.';
    header('Location: login.php');
    exit;
}
?>

Результат: при успешном входе пользователь перенаправляется на dashboard.php, при ошибке возвращается обратно с сообщением в сессии. Важно: логирование входа полезно для аудита.

Пример 2. Форма входа с отображением ошибок и сохранением введённого email

Пример

<!DOCTYPE html>
<html lang="ru">
<head><meta charset="UTF-8"><title>Вход</title></head>
<body>
<?php session_start(); ?>
<form method="post" action="login.php">
    <?php if (isset($_SESSION['error'])): ?>
        <p class="error"><?= htmlspecialchars($_SESSION['error'], ENT_QUOTES, 'UTF-8') ?></p>
        <?php unset($_SESSION['error']); ?>
    <?php endif; ?>
    <label>Email: <input type="email" name="email" value="<?= htmlspecialchars($_SESSION['old_email'] ?? '', ENT_QUOTES, 'UTF-8') ?>" required></label><br>
    <label>Пароль: <input type="password" name="password" required></label><br>
    <input type="submit" value="Войти">
</form>
</body>
</html>
Вывод: форма с предзаполненным email и сообщением об ошибке, если сессия содержит соответствующие данные. После отображения ошибка и старый email удаляются из сессии.

Пример 3. Вход через API с возвратом JSON и использованием токенов (без сессий)

Пример

<?php
header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => 'Method not allowed']);
    exit;
}

$data = json_decode(file_get_contents('php://input'), true);
if (!$data || empty($data['email']) || empty($data['password'])) {
    http_response_code(400);
    echo json_encode(['error' => 'Email and password required']);
    exit;
}

// проверка пользователя в БД, password_verify...
// если успешно, генерируем JWT или простой токен
$token = bin2hex(random_bytes(32));
// сохраняем токен в БД для пользователя
$stmt = $pdo->prepare('INSERT INTO api_tokens (user_id, token, expires_at) VALUES (:uid, :token, :expires)');
$stmt->execute(['uid' => $user['id'], 'token' => $token, 'expires' => date('Y-m-d H:i:s', time() + 3600)]);

http_response_code(200);
echo json_encode(['token' => $token, 'expires_in' => 3600]);

Результат: клиент получает токен, который использует для последующих запросов. Этот подход подходит для SPA и мобильных приложений.

Исходный код страницы входа PHP - comments

En
Login php src (php)