Организация аутентификации PHP на локальном сервере

Раздел: Веб-разработка -> настройка локального сервера

Методы создания локального логина в PHP

Основное решение: сессии + база данных MySQL

Этот подход обеспечивает надёжное хранение учётных записей и гибкое управление доступом. Для локального сервера (XAMPP, OpenServer) достаточно стандартных средств PHP и MySQL.

Как реализовать защищённый вход на localhost с использованием сессий и MySQL?

Последовательность шагов:

  1. Создать базу данных и таблицу users (id, login, password_hash, created_at).
  2. Настроить подключение через PDO (prepared statements).
  3. Создать форму регистрации и скрипт обработки с хешированием пароля (password_hash).
  4. Создать форму входа, проверять пароль через password_verify, устанавливать сессионную переменную.
  5. На защищённых страницах проверять наличие сессии.

<?php
// config.php
define('DB_HOST', 'localhost');
define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASS', '');

try {
    $pdo = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die('Ошибка подключения к БД');
}
?>

Http localhost login php (локальный логин php)


<?php
// register.php
session_start();
require 'config.php';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $login = trim($_POST['login']);
    $password = $_POST['password'];
    $hash = password_hash($password, PASSWORD_DEFAULT);
    
    $stmt = $pdo->prepare('INSERT INTO users (login, password_hash) VALUES (?, ?)');
    if ($stmt->execute([$login, $hash])) {
        $_SESSION['message'] = 'Регистрация успешна';
        header('Location: login.php');
        exit;
    } else {
        $error = 'Ошибка регистрации';
    }
}
?>

<?php
// login.php
session_start();
require 'config.php';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $login = trim($_POST['login']);
    $password = $_POST['password'];
    
    $stmt = $pdo->prepare('SELECT * FROM users WHERE login = ?');
    $stmt->execute([$login]);
    $user = $stmt->fetch();
    
    if ($user && password_verify($password, $user['password_hash'])) {
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['login'] = $user['login'];
        header('Location: dashboard.php');
        exit;
    } else {
        $error = 'Неверный логин или пароль';
    }
}
?>

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

  • Использование устаревшего хеша md5 или sha1 (решение: password_hash).
  • Отсутствие prepared statements (риск SQL-инъекций).
  • Неправильная настройка путей сессий (сессии не сохраняются).
  • Игнорирование фильтрации ввода (trim, strip_tags).

Как защитить страницу без базы данных с помощью HTTP Basic Auth?

Подходит для быстрого ограничения доступа к папке. Сервер отправляет заголовок 401, браузер показывает диалог ввода логина и пароля.


<?php
// .htaccess (Apache) или конфигурация сервера
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /path/to/.htpasswd
Require valid-user

Файл .htpasswd создаётся утилитой htpasswd или онлайн-генератором. Хранятся логин и хеш пароля.

Проблема:

Нет возможности персонализировать страницу входа; пароль передаётся в открытом виде без HTTPS (на localhost обычно не критично).

Как реализовать логин с хранением данных в файле?

Используется для очень простых проектов без MySQL. Создаётся файл users.json с массивом логинов и хешей паролей.


// users.json
[
    {"login": "admin", "password_hash": "$2y$10$..."}
]

<?php
// file_login.php
$users = json_decode(file_get_contents('users.json'), true);
foreach ($users as $user) {
    if ($user['login'] === $login && password_verify($password, $user['password_hash'])) {
        // установка сессии
    }
}

Проблемы:

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

Как упростить разработку с помощью готовой библиотеки?

Библиотеки вроде PHPass или компонента Symfony Security предоставляют готовые классы для хеширования и проверки. Пример с использованием phpass (устарел, но показателен).


require 'PasswordHash.php';
$hasher = new PasswordHash(8, false);
$hash = $hasher->HashPassword($password);
$check = $hasher->CheckPassword($password, $hash);

Современная альтернатива - использование password_hash напрямую, что уже является лучшей практикой.

Расширенные примеры с пошаговым кодом и результатами.

Пример 1. Полная система регистрации и входа на PDO с защитой от CSRF

Пример

<?php
// config.php
session_start();
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// create_table.sql
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    login VARCHAR(50) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Пример

<?php
// generate_token.php
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>
Пример

<?php
// register.php
require 'config.php';
require 'generate_token.php';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        die('CSRF token error');
    }
    $login = filter_input(INPUT_POST, 'login', FILTER_SANITIZE_STRING);
    $password = $_POST['password'];
    $hash = password_hash($password, PASSWORD_BCRYPT);
    
    $stmt = $pdo->prepare('INSERT INTO users (login, password_hash) VALUES (?, ?)');
    try {
        $stmt->execute([$login, $hash]);
        $_SESSION['message'] = 'Успешная регистрация';
        header('Location: login.php');
        exit;
    } catch (PDOException $e) {
        if ($e->getCode() == 23000) {
            $error = 'Логин уже занят';
        } else {
            $error = 'Ошибка базы данных';
        }
    }
}
?>

Результат работы (при успешной регистрации):

Перенаправление на login.php с сообщением 'Успешная регистрация'

Пример 2. Защищённая страница dashboard.php

Пример

<?php
session_start();
if (!isset($_SESSION['user_id'])) {
    header('Location: login.php');
    exit;
}
?>
<h2>Добро пожаловать, <?php echo htmlspecialchars($_SESSION['login']); ?>!</h2>

Результат (если сессия активна):

Добро пожаловать, admin!

Пример 3. Использование файлового хранилища с сериализацией

Пример

// users.txt (одна строка на пользователя: login:hash)
admin:$2y$10$abcdef...

// file_check.php
$users = file('users.txt', FILE_IGNORE_NEW_LINES);
$found = false;
foreach ($users as $line) {
    list($login, $hash) = explode(':', $line, 2);
    if ($login === $_POST['login'] && password_verify($_POST['password'], $hash)) {
        $found = true;
        break;
    }
}
if ($found) { /* успех */ }

Результат:

При совпадении логина и пароля устанавливается сессия.

Пример 4. Отладка сессий на localhost

Пример

<?php
session_start();
ini_set('session.save_path', '/tmp'); // явно указать путь
var_dump(session_save_path());
?>

Возможная проблема:

Сессии не сохраняются из-за отсутствия прав на запись в папку сессий. Решение: проверить права, указать свой путь через session_save_path().

локальный логин PHP - comments

En
Http localhost login php (php)