<MyRusakov.ru />

Профессия Web-разработчик

Профессия Web-разработчик

Этот комплект за 8 месяцев превратит Вас в Web-разработчика с нуля. Учиться достаточно 1 час в день.

Начнёте Вы с HTML, CSS и вёрстки сайтов. Потом перейдёте к программированию и JavaScript. Затем изучите PHP, MySQL, SQL, Python. Изучите Web-фреймворки Laravel и Django. Создадите 5 своих сайтов для портфолио.

Комплект содержит:

- 540 видеоуроков

- 110 часов видео

- 1205 заданий для закрепления материала из уроков

- 5 финальных тестов

- 7 сертификатов

- 12 Бонусных курсов

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

Хеширование паролей в PHP: password_hash и password_verify для безопасной авторизации

Хеширование паролей в PHP: password_hash и password_verify для безопасной авторизации

Поисковый запрос, под который написана эта статья: PHP password_hash password_verify. Если вы делаете регистрацию, личный кабинет или админку, первое правило безопасности простое: никогда не храните пароль пользователя как обычный текст. В PHP для этого есть встроенные функции password_hash() и password_verify().

Почему нельзя хранить пароль как есть

Допустим, пользователь ввёл пароль qwerty123, а вы записали его в базу данных без изменений. Если база утечёт, злоумышленник сразу получит доступ к аккаунтам. Плохо и другое решение — использовать md5 или sha1. Эти алгоритмы быстрые, устаревшие и легко перебираются по словарям.

Правильный подход — хранить не пароль, а его криптографический хеш, созданный специальным алгоритмом для паролей. В PHP это делается одной функцией:

<?php
$password = 'secret123';

$hash = password_hash($password, PASSWORD_DEFAULT);

echo $hash;

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

Что делает password_hash()

Функция password_hash() создаёт безопасный хеш пароля. Важный момент: она автоматически добавляет соль. Поэтому два одинаковых пароля почти всегда дадут разные хеши:

<?php
$password = 'secret123';

echo password_hash($password, PASSWORD_DEFAULT) . PHP_EOL;
echo password_hash($password, PASSWORD_DEFAULT) . PHP_EOL;

Новичков это иногда пугает: «Как тогда сравнивать пароль?» Сравнивать хеши вручную не нужно. Для этого есть password_verify().

Как проверить пароль через password_verify()

При входе пользователь вводит пароль. Вы берёте хеш из базы данных и передаёте оба значения в password_verify():

<?php
$passwordFromForm = 'secret123';
$hashFromDatabase = '$2y$10$exampleExampleExampleExampleExampleExampleExample';

if (password_verify($passwordFromForm, $hashFromDatabase)) {
    echo 'Пароль верный';
} else {
    echo 'Неверный пароль';
}

В реальном проекте хеш будет получен из базы данных по email, логину или ID пользователя.

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

Ниже упрощённый пример обработки формы регистрации. Главное — перед сохранением пароля вызвать password_hash():

<?php
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';

if ($email === '' || $password === '') {
    exit('Заполните email и пароль');
}

if (strlen($password) < 8) {
    exit('Пароль должен быть не короче 8 символов');
}

$passwordHash = password_hash($password, PASSWORD_DEFAULT);

// Далее $passwordHash сохраняется в базу данных,
// например в поле password_hash.

echo 'Пользователь зарегистрирован';

Поле в базе данных лучше назвать не password, а password_hash. Так понятнее, что там хранится не исходный пароль.

Пример входа пользователя

При авторизации алгоритм такой: найти пользователя по email, получить его хеш пароля, проверить введённый пароль через password_verify().

<?php
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';

// Допустим, эти данные пришли из базы данных.
$user = [
    'id' => 15,
    'email' => 'user@example.com',
    'password_hash' => password_hash('secret123', PASSWORD_DEFAULT),
];

if (!$user) {
    exit('Пользователь не найден');
}

if (!password_verify($password, $user['password_hash'])) {
    exit('Неверный email или пароль');
}

session_start();
$_SESSION['user_id'] = $user['id'];

echo 'Вы вошли';

Обратите внимание на сообщение об ошибке. В реальном проекте часто лучше писать одинаково: Неверный email или пароль. Так вы не подсказываете злоумышленнику, существует ли такой email.

PASSWORD_DEFAULT или PASSWORD_BCRYPT?

В большинстве случаев используйте PASSWORD_DEFAULT:

<?php
$hash = password_hash($password, PASSWORD_DEFAULT);

Это рекомендуемый вариант для обычных проектов. PHP сам выберет актуальный алгоритм по умолчанию. Сейчас часто используется bcrypt, но в будущем значение может измениться. Поэтому важно выделять в базе достаточно места под хеш: обычно используют VARCHAR(255).

Если вам нужно явно использовать bcrypt, можно написать так:

<?php
$hash = password_hash($password, PASSWORD_BCRYPT);

Настройка cost: когда это нужно

Для bcrypt можно задать параметр cost. Чем он выше, тем медленнее создаётся хеш. Это усложняет перебор паролей, но увеличивает нагрузку на сервер.

<?php
$hash = password_hash($password, PASSWORD_BCRYPT, [
    'cost' => 12,
]);

Не ставьте слишком большое значение «на всякий случай». Проверьте скорость на вашем сервере. Хороший ориентир: хеширование одного пароля должно занимать заметное, но приемлемое время, например десятки или сотни миллисекунд, а не несколько секунд.

Как обновлять старые хеши

PHP умеет проверять, не устарел ли хеш. Для этого есть password_needs_rehash(). Это полезно, если вы изменили алгоритм или параметры cost.

<?php
if (password_verify($password, $user['password_hash'])) {
    if (password_needs_rehash($user['password_hash'], PASSWORD_DEFAULT)) {
        $newHash = password_hash($password, PASSWORD_DEFAULT);

        // Обновите password_hash пользователя в базе данных.
    }

    echo 'Успешный вход';
}

Так можно постепенно обновлять безопасность без принудительного сброса паролей всем пользователям.

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

  • Хранить пароль в открытом виде — самая опасная ошибка.
  • Использовать md5 или sha1 — эти функции не подходят для паролей.
  • Сравнивать хеши вручную — используйте только password_verify().
  • Обрезать хеш в базе — используйте поле достаточной длины, например VARCHAR(255).
  • Отправлять пароль обратно пользователю — при восстановлении пароля нужно создавать ссылку или токен сброса, а не высылать старый пароль.

Минимальная структура таблицы

Для старта таблица пользователей может выглядеть так:

CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(190) NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    created_at DATETIME NOT NULL
);

В реальном проекте добавляют поля статуса, роли, даты обновления, токены подтверждения email и другие данные.

Практические рекомендации

  • Проверяйте минимальную длину пароля, например от 8 или 10 символов.
  • Не ограничивайте пароль слишком жёстко: пользователи должны иметь возможность использовать длинные фразы.
  • Всегда используйте HTTPS на сайте с авторизацией.
  • После входа сохраняйте в сессию ID пользователя, а не весь объект пользователя и не пароль.
  • Для запросов к базе используйте подготовленные выражения, чтобы не получить SQL-инъекцию.

Если вы хотите не просто выучить отдельные функции, а собрать полноценную регистрацию, авторизацию, работу с MySQL и защиту проекта на практике, посмотрите курс PHP и MySQL с нуля до уверенной разработки — он хорошо дополняет эту тему.

Итог

password_hash() и password_verify() — базовый минимум для безопасной работы с паролями в PHP. При регистрации создавайте хеш и сохраняйте его в базу. При входе проверяйте пароль через password_verify(). Не используйте md5, не храните пароли открытым текстом и заранее выделяйте достаточно места под хеш в таблице пользователей.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (https://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: https://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: https://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.