Создание системы аутентификации через регистрацию на localhost
Регистрация на локальном сервере PHP: подробное руководство
Разработка системы регистрации на локальном сервере позволяет отладить аутентификацию без публичного доступа. В этой статье рассмотрены несколько подходов.
Основное решение: использование mysqli и password_hash
Этот способ подходит для простых проектов на локальном сервере с MySQL.
Как создать базовую регистрацию с защитой от SQL инъекций?
Для хранения пользователей создается таблица users с полями id, username, email, password, created_at. В обработчике используются подготовленные запросы.
<?php
session_start();
$conn = new mysqli('localhost', 'root', '', 'test');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$email = $_POST['email'];
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$stmt = $conn->prepare('INSERT INTO users (username, email, password) VALUES (?, ?, ?)');
$stmt->bind_param('sss', $username, $email, $password);
if ($stmt->execute()) {
$_SESSION['user_id'] = $conn->insert_id;
header('Location: dashboard.php');
} else {
$error = 'Ошибка регистрации: ' . $conn->error;
}
}
?>Admin index php login php (страница входа администратора php)
Важно: необходимо проверять уникальность email перед вставкой.
Типичные ошибки: отсутствие проверки на существование email, недостаточная длина поля password (рекомендуется varchar(255) для хэша), неправильный порядок параметров в bind_param.
Вариант 1: Использование PDO вместо mysqli
Вопрос: Как переписать регистрацию с PDO для большей гибкости?
PDO поддерживает разные СУБД и обеспечивает единый интерфейс. Пример с именованными плейсхолдерами:
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $pdo->prepare('INSERT INTO users (username, email, password) VALUES (:username, :email, :password)');
$stmt->execute([
':username' => $_POST['username'],
':email' => $_POST['email'],
':password' => password_hash($_POST['password'], PASSWORD_DEFAULT)
]);Php code login (код страницы входа php)
Проблемы: необходимо установить режим ошибок (PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION), чтобы отлавливать исключения. Часто забывают указать кодировку (SET NAMES utf8).
Вариант 2: Правильное хэширование паролей
Вопрос: Какой алгоритм хэширования выбрать для паролей?
В PHP используется функция password_hash, которая автоматически выбирает стойкий алгоритм (сейчас bcrypt). Пароль хранится в виде строки длиной 60 символов (для bcrypt). При проверке используется password_verify.
if (password_verify($input_password, $hash_from_db)) { /* авторизация */ }Request login php (запрос на вход php)
Ошибка: применение старых алгоритмов (md5, sha1) без соли. Проблемы с устаревшими PHP версиями (до 5.5) - нужно использовать compat-пакет.
Вариант 3: Регистрация с подтверждением email
Вопрос: Как добавить проверку email перед активацией учетной записи?
В таблицу users добавляются поля token и active. После регистрации отправляется письмо со ссылкой. Пример генерации токена:
$token = bin2hex(random_bytes(16));
// сохранение token в БД вместе с пользователем
// отправка email: mail($email, 'Подтверждение', "Перейдите по ссылке: http://localhost/confirm.php?token=$token");Localhost register php (регистрация на локальном сервере)
При активации проверяется token и устанавливается active = 1.
На локальном сервере почта часто не отправляется. Рекомендуется использовать PHPMailer с SMTP (например, Mailtrap) или сервис MailHog. Проблемы с безопасностью токена: его рекомендуется хэшировать перед сохранением (например, hash('sha256', $token)).
Вариант 4: JSON API для регистрации
Вопрос: Как организовать регистрацию через REST API для одностраничного приложения?
Обработчик принимает JSON, возвращает JSON:
header('Content-Type: application/json; charset=utf-8');
$data = json_decode(file_get_contents('php://input'), true);
// валидация, хэширование, вставка
echo json_encode(['success' => true, 'message' => 'Регистрация прошла успешно']);
Проблемы: CORS (нужно добавить Access-Control-Allow-Origin), неверный Content-Type запроса, отсутствие обработки ошибок валидации.
Расширенные примеры регистрации
Пример 1. Полная регистрация с валидацией и выводом ошибок.
<?php
session_start();
require_once 'db.php';
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username']);
$email = trim($_POST['email']);
$password = $_POST['password'];
$confirm = $_POST['confirm'];
// валидация
if (strlen($username) < 3) $errors[] = 'Имя слишком короткое';
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = 'Некорректный email';
if (strlen($password) < 8) $errors[] = 'Пароль менее 8 символов';
if ($password !== $confirm) $errors[] = 'Пароли не совпадают';
// проверка уникальности email
$stmt = $pdo->prepare('SELECT id FROM users WHERE email = ?');
$stmt->execute([$email]);
if ($stmt->fetch()) $errors[] = 'Email уже зарегистрирован';
if (empty($errors)) {
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare('INSERT INTO users (username, email, password) VALUES (?, ?, ?)');
$stmt->execute([$username, $email, $hash]);
$_SESSION['user_id'] = $pdo->lastInsertId();
header('Location: profile.php');
exit;
}
}
?>
Результат: при успехе пользователь перенаправляется на profile.php, иначе ошибки выводятся в формате списка.
Пример 2. Регистрация с подтверждением email через PHPMailer.
// после сохранения пользователя с токеном
use PHPMailer\PHPMailer\PHPMailer;
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'your_username';
$mail->Password = 'your_password';
$mail->Port = 2525;
$mail->setFrom('from@example.com', 'Mailer');
$mail->addAddress($email);
$mail->Subject = 'Подтверждение регистрации';
$mail->Body = "Ваш токен: $token. Ссылка: http://localhost/confirm.php?token=$token";
$mail->send();
Результат: пользователь получает письмо с токеном. После перехода по ссылке его аккаунт активируется.
Пример 3. REST API регистрации с ответом в JSON.
// api/register.php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON']);
exit;
}
// валидация (как в примере 1) (опущена для краткости)
// вставка
echo json_encode(['success' => true, 'redirect' => '/login']);
Результат: клиент (JavaScript) отправляет POST с JSON и получает JSON ответ.