nmk

Лабораторна робота №17 (2 години)

Тема: Реєстрація користувачів (Безпека). Створення форми реєстрації. Реальне хешування нового пароля у базі (password_hash) та перевірка при логіні (password_verify).

Мета: Навчитися працювати зі стандартами безпеки зберігання приватних користувацьких даних: правилам генерації “солоних” гешів (salting and hashing), і замінити фейкову авторизацію на реальну.

Технологічний стек: PHP Password Hashing API (password_hash(), password_verify()), SQL (INSERT INTO users, SELECT ... FROM users).

Завдання

  1. Створити форму реєстрації нових користувачів.
  2. Провести валідацію введених даних при реєстрації (унікальність Email).
  3. Зберегти користувача в таблицю users бази даних, використовуючи функцію криптографічного хешування паролів password_hash().
  4. Змінити логіку форми логіну з Лаб. №9, щоб вона зчитувала реального користувача з БД і порівнювала збережений хеш із введеним поролем за допомогою password_verify().

Хід виконання роботи

Крок 1. Створення форми реєстрації (register.php)

У файлі register.php створіть HTML-форму із полями “Ім’я”, “Електронна пошта” (Email) та “Пароль”. Метод POST. В PHP напишіть обробник, який (після перевірки !empty() усіх полів) підготує пароль до зберігання:

$plainPassword = $_POST['password'];
// Конвертація "чистого" паролю у зашифрований рядок
// за допомогою безпечного алгоритму BCRYPT:
$hashedPassword = password_hash($plainPassword, PASSWORD_DEFAULT);

Тепер пароль (наприклад, “12345”) виглядатиме як довгий випадковий набір символів на кшталт: $2y$10$C82a...

Крок 2. Збереження до БД

Перевірте, чи не існує вже такого користувача (запит SELECT id FROM users WHERE email = :email). Якщо є — додайте в масив $errors повідомлення “Ця пошта вже зайнята”. Якщо все добре, виконайте підготовлений INSERT INTO users (username, email, password) VALUES (:name, :email, :pass). У значення :pass обов’язково передайте підготовлений на попередньому кроці $hashedPassword! Якщо вставка пройшла успішно, автоматично перенаправте користувача на сторінку login.php.

Крок 3. Переробка системи Входу (login.php)

Відкрийте свій login.php. Видаліть фейкову перевірку “admin / 12345”. Тепер при отриманні POST з логіном (емейлом) та паролем спочатку знайдіть рядок із користувачем у БД: SELECT * FROM users WHERE email = :email LIMIT 1. Отримайте масив асоціативного рядка (або false, якщо пошти немає) через метод $stmt->fetch().

Якщо користувача знайдено if ($user), перевірте пароль за допомогою спеціальної функції PHP, яка сама аналізує сіль і алгоритм створення password_hash:

if (password_verify($_POST['password'], $user['password'])) { // в базі пароль у стовпці password
    // Якщо тут - паролі успішно збіглись!
    $_SESSION['is_logged_in'] = true;
    $_SESSION['user_id'] = $user['id'];
    $_SESSION['user_name'] = $user['username'];
    header('Location: index.php'); exit;
} else {
    // Ввели неправильний пароль
    $errors[] = "Невірний пароль!";
}

Крок 4. Тестування системи

Зареєструйе нового користувача через форму. Відкрийте phpMyAdmin, перейдіть до таблиці users та подивіться, як захищено ваш пароль. Спробуйте залогінитися зі щойно створеними даними (правильними і навмисно хибними).

Контрольні запитання

  1. Чому зберігати паролі у відкритому “видимому тексті” (plain text) категорично заборонено? До яких наслідків це може призвести під час витоку бази даних (Database Leak, SQL Dump)?
  2. Чим відрізняється шифрування від хешування? (Яке з них можна дешифрувати і отримати назад “12345” через ключ, а яке — неможливо повернути до початкового стану?)
  3. Що таке механізм “Password Salt” (Сіль) в алгоритмі хешування і чому функція password_hash автоматично додає її до хешу під час генерації? (Підказка: Райдужні таблиці - Rainbow Tables).
  4. Чому категорично не можна перевіряти введений користувачем пароль через звичайне порівняння if(md5($_POST['password']) === $user['password'])? Чому необхідно використовувати виключно password_verify?
  5. Звідки функція password_verify під час логіну бере інформацію про те, який саме алгоритм (bcrypt, argon2id) та “сіль” використовувались для створення пароля, щоб змоділювати його повторно?

Вимоги до звіту

  1. У файл lab17.md скинути фрагмент коду register.php (де хешується пароль) та обробник логіну з login.php.
  2. Додати скриншот браузера з відкритою сторінкою phpMyAdmin (або просто результати запиту), що ілюструє вміст таблиці users. (На скриншоті повинно бути видно збережений довгий хеш замість звичайного паролю).
  3. Здійснити черговий коміт на GitHub. Надати посилання.
  4. Надати відповіді на контрольні запитання.