Модуль "Users", - users.passrecover.php в Cotonti CMF

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

Опубликовано в: Модули в Cotonti из коробки

Общее описание файла "users.passrecover.php"

Файл "users.passrecover.php" в системе Cotonti CMF предназначен для обработки процесса восстановления пароля пользователя. Он играет важную роль в механизме аутентификации и восстановления доступа к учетной записи на сайте. Этот файл размещен в директории /modules/users/inc, что указывает на его принадлежность к модулю пользователей, отвечающему за управление профилями и аутентификацию пользователей.

Основное назначение файла и его место в системе Cotonti

Назначение:

  • Главной задачей данного файла является обработка запросов на восстановление пароля пользователей. Когда пользователь забывает свой пароль, этот файл помогает ему вернуть доступ к учетной записи путем отправки инструкции по восстановлению на его электронную почту или непосредственно сброса пароля с помощью проверочного кода.

Место в системе:

  • Этот файл является частью модуля "users" в рамках системы управления пользователями и связан с функционалом восстановления паролей. Он работает в связке с другими модулями сайта, такими как обработка форм, отправка сообщений по электронной почте, а также с системой безопасности.

Взаимодействие с другими частями системы

Файл взаимодействует с несколькими компонентами системы Cotonti:

  1. База данных – запросы к базе данных выполняются для получения информации о пользователе по его электронной почте, а также для обновления данных о пользователе после сброса пароля.
  2. Система безопасности – используются функции для защиты от атак типа CSRF (например, через вызовы cot_shield_protect()).
  3. Система отправки почты – отправляются электронные письма с инструкциями по восстановлению пароля.
  4. Шаблонная система – используется для вывода интерфейса для восстановления пароля (например, через создание и вывод шаблона с помощью XTemplate).

Основные используемые переменные, методы, функции, классы

  1. $a – Параметр запроса, определяющий текущую операцию: может быть значением 'request' или 'auth'.
  2. $email – Электронная почта пользователя, передаваемая в запросе для поиска соответствующего пользователя в базе данных.
  3. $v – Код, связанный с восстановлением пароля (например, проверочный ключ).
  4. $msg – Сообщение статуса восстановления пароля.
  5. Cot::$usr['id'] – ID текущего пользователя (используется для проверки, не является ли пользователь авторизованным).
  6. Cot::$db – Объект для работы с базой данных (выполняет запросы на получение и обновление данных пользователей).
  7. cot_shield_protect() – Функция защиты от атак CSRF, используется для предотвращения подделки запросов.
  8. cot_shield_update() – Функция для обновления информации о защите (например, обновление токена безопасности).
  9. cot_log() – Функция для записи логов с определенным уровнем серьезности (например, при ошибках восстановления пароля).
  10. cot_redirect() – Функция для перенаправления пользователя на другую страницу.
  11. cot_mail() – Функция для отправки электронной почты пользователю.
  12. Cot::$cfg – Конфигурация системы, которая используется для получения настроек сайта.
  13. Cot::$L – Локализация текста для вывода сообщений на разных языках.
  14. Cot::$R – Ресурсы системы, например, код для запрета индексации страницы поисковиками.
  15. XTemplate – Класс для работы с шаблонами и выводом HTML-кода.
  16. UsersHelper::getFullName() – Метод для получения полного имени пользователя.

Суть содержания кода

Файл "users.passrecover.php" состоит из нескольких блоков, каждый из которых выполняет конкретную задачу:

  1. Запрос на восстановление пароля (a = 'request'):

    • Проверяется, была ли введена электронная почта.
    • Выполняется поиск пользователя по введенному email в базе данных.
    • Если пользователя с таким email нет, выводится ошибка.
    • Если пользователь найден, для него генерируется уникальный ключ восстановления пароля, который сохраняется в базе данных.
    • Пользователю отправляется email с ссылкой на страницу для изменения пароля.
    • Если пользователю отправлено письмо, он перенаправляется на страницу с подтверждением.
  2. Аутентификация по ссылке восстановления пароля (a = 'auth'):

    • Проверяется валидность кода восстановления.
    • Если код не найден или неверен, происходит редирект на страницу с ошибкой.
    • Если код верный, генерируется новый пароль для пользователя и обновляются его данные в базе данных.
    • Пользователю отправляется письмо с новым паролем.
  3. Отображение страницы восстановления пароля:

    • Формируется шаблон страницы, который выводит форму для запроса на восстановление пароля.
    • Используются хуки для расширяемости, позволяя подключать дополнительные модули или функционал.

Возможности для владельца сайта

Владелец сайта может использовать этот сценарий для обеспечения пользователей возможностью восстановить доступ к их учетным записям в случае потери пароля. Процесс включает:

  • Введение электронной почты для получения инструкции по восстановлению.
  • Введение проверочного кода для сброса пароля.
  • Генерацию нового пароля и отправку его пользователю.

Также, используя хуки, можно легко расширять или изменять поведение этой системы для нужд конкретного сайта.

Стиль написания PHP-кода и совместимость с версиями PHP

Код написан с использованием стандартов PHP, типичных для фреймворков, таких как Cotonti CMF. Применяется объектно-ориентированный подход для работы с базой данных и шаблонами. Стиль кода чистый, с ясной структурой и комментариями, что способствует хорошей читаемости и поддержке кода.

Код совместим с версиями PHP начиная с PHP 5.6 и выше, так как используется поддерживаемые конструкции и функции PHP. Для работы с более новыми версиями PHP может потребоваться адаптация некоторых функций, однако в целом код будет работать без изменений в версиях от 7.0 и выше.

 
/**
 * Отправляет письма пользователям для восстановления их паролей
 *
 * @package Users
 * @copyright (c) Cotonti Team
 * @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
 *
 * @var string $a
 */

use cot\users\UsersHelper; // Подключение класса UsersHelper, который используется для работы с пользователями, например для восстановления пароля.

defined('COT_CODE') or die('Wrong URL'); // Проверка на правильность входного URL. Если константа COT_CODE не определена, то доступ к скрипту запрещен.

$v = cot_import('v', 'G', 'TXT'); // Получение параметра 'v' из глобальных данных (GET-запрос), который, вероятно, будет использоваться для валидации или идентификации запроса.

$email = cot_import('email', 'P', 'TXT'); // Получение параметра 'email' из POST-запроса. Это адрес электронной почты, который будет использоваться для восстановления пароля.

 /* === Hook === */
foreach (cot_getextplugins('users.passrecover.first') as $pl) { // Загрузка плагинов, зарегистрированных для события 'users.passrecover.first'. Это позволяет расширить функциональность.
	include $pl; // Включение каждого плагина, найденного для данного события.
}
/* ===== */

cot_block(Cot::$usr['id'] === 0); // Проверка, что пользователь не авторизован (id пользователя равно 0), блокирует доступ, если пользователь авторизован.

$msg = ''; // Инициализация переменной $msg для хранения сообщений, например, сообщений об ошибках или успешных действиях.

 

if ($a === 'request' && $email !== '') { // Проверка, если действие равно 'request' и email не пустой.
	cot_shield_protect(); // Защита от CSRF-атак с использованием токена защиты.

	$data = Cot::$db->query( // Выполнение SQL-запроса для получения данных пользователя с указанным email.
        'SELECT * FROM ' . Cot::$db->users . ' WHERE user_email = ? ORDER BY user_id ASC', 
        $email // Подставляем email в запрос.
    )->fetchAll(); // Извлекаем все записи, соответствующие email.

    if (empty($data)) { // Если данных по email не найдено.
        cot_shield_update(10, "Password recovery requested"); // Обновление защиты, фиксируем запрос на восстановление пароля.
        $env['status'] = '403 Forbidden'; // Устанавливаем статус 403, доступ запрещен.
        cot_log('Pass recovery failed, user email: ' . $email, 'users', 'passrecover', 'error'); // Логируем ошибку восстановления пароля.
        cot_redirect(cot_url('message', 'msg=154', '', true)); // Перенаправляем на страницу с сообщением об ошибке.
    }

    $users = []; // Массив для хранения данных пользователей.
    $userIds = []; // Массив для хранения идентификаторов пользователей.

    foreach ($data as $row) { // Проходим по каждому найденному пользователю.
        $users[$row['user_id']] = $row; // Добавляем пользователя в массив по ID.
        $users[$row['user_id']]['groups'] = []; // Инициализируем массив групп для каждого пользователя.
        $userIds[] = $row['user_id']; // Добавляем ID пользователя в массив.
    }
    unset($data); // Освобождаем память от переменной $data.

    $groups = Cot::$db->query( // Выполнение SQL-запроса для получения групп пользователей.
        'SELECT gru_userid, gru_groupid FROM ' . Cot::$db->groups_users
        . ' WHERE gru_userid IN (' . implode(',', $userIds) . ')')
        ->fetchAll(); // Извлекаем все группы для пользователей.

    if (!empty($groups)) { // Если группы найдены.
        foreach ($groups as $group) { // Проходим по всем группам.
            $users[$group['gru_userid']]['groups'][] = (int) $group['gru_groupid']; // Добавляем группу пользователю.
        }
    }

    $emailFound = false; // Флаг для проверки, был ли найден хотя бы один пользователь с данным email.
    foreach ($users as $user) { // Проходим по всем пользователям.
        cot_fillGroupsForUser($user); // Заполняем группы для пользователя.

        if (in_array(COT_GROUP_INACTIVE, $user['groups'], true)) { // Если пользователь в группе неактивных.
            cot_log( // Логируем ошибку восстановления пароля для неактивного пользователя.
                'Password recovery failed, user inactive: ' . $user['user_name'],
                'users',
                'passrecover', 'error'
            );
            continue; // Пропускаем пользователя и продолжаем проверку для других.
        }

        if (in_array(COT_GROUP_BANNED, $user['groups'], true)) { // Если пользователь в группе забаненных.
            cot_log( // Логируем ошибку восстановления пароля для забаненного пользователя.
                'Password recovery failed, user banned: ' . $user['user_name'],
                'users',
                'passrecover',
                'error'
            );
            continue; // Пропускаем пользователя и продолжаем проверку для других.
        }

		$validationKey = $user['user_lostpass']; // Получаем ключ для восстановления пароля пользователя.
		if (empty($validationkey) || $validationkey == '0') { // Если ключ восстановления пуст или равен 0.
            $validationKey = md5(microtime()); // Генерируем новый ключ для восстановления.
			Cot::$db->update( // Обновляем данные пользователя в базе данных.
                Cot::$db->users,
                ['user_lostpass' => $validationKey, 'user_lastip' => Cot::$usr['ip']], // Обновляем ключ и IP-адрес.
                'user_id = ?',
                $user['user_id']
            );
		}

		$changePasswordUrl = Cot::$cfg['mainurl'] . '/' // Формируем ссылку для изменения пароля.
            . cot_url('users', ['m' => 'passrecover', 'a' => 'auth', 'v' => $validationKey], '', true); // Добавляем параметр для авторизации с уникальным ключом.

        $mailBody = sprintf( // Формируем текст письма для восстановления пароля.
            Cot::$L['pasrec_email1'],
            UsersHelper::getInstance()->getFullName($user), // Имя пользователя.
            $changePasswordUrl, // Ссылка для изменения пароля.
            Cot::$usr['ip'], // IP-адрес пользователя.
            cot_date('datetime_medium') // Дата и время запроса.
        );
        $mailBody .= "\n\n " . Cot::$L['aut_contactadmin']; // Добавляем информацию для связи с администратором.

        cot_mail($email, Cot::$L['pasrec_title'], $mailBody); // Отправляем письмо с инструкциями по восстановлению пароля.

        $emailFound = true; // Устанавливаем флаг, что email найден и письмо отправлено.
		if (!Cot::$cfg['useremailduplicate']) { // Если не разрешено дублирование email.
            break; // Прерываем цикл, так как письмо отправлено.
        }
	}

    if (!$emailFound) { // Если email не был найден среди пользователей.
        cot_shield_update(10, "Password recovery requested"); // Обновляем защиту от атак.
        $env['status'] = '403 Forbidden'; // Устанавливаем статус 403, доступ запрещен.
        cot_log('Pass recovery failed, user email: ' . $email, 'users', 'passrecover', 'error'); // Логируем ошибку восстановления пароля.
        cot_redirect(cot_url('message', 'msg=154', '', true)); // Перенаправляем на страницу с сообщением об ошибке.
    }

    $msg = 'request'; // Устанавливаем переменную для статуса запроса.

	cot_shield_update(60, "Password recovery email sent"); // Обновляем защиту, фиксируем, что письмо для восстановления пароля отправлено.
} elseif ($a === 'auth' && mb_strlen($v) === 32) { // Проверка, если действие равно 'auth' и длина переменной $v равна 32 (это ключ для восстановления пароля).
	cot_shield_protect(); // Защита от CSRF-атак с использованием токена защиты.

	$user = Cot::$db->query( // Выполнение SQL-запроса для поиска пользователя по ключу восстановления пароля.
        'SELECT * FROM ' . Cot::$db->users . ' WHERE user_lostpass = ? LIMIT 1', 
        $v // Подставляем ключ восстановления.
    )->fetch(); // Извлекаем первого найденного пользователя.

    if (!$user) { // Если пользователь с таким ключом не найден.
        $env['status'] = '403 Forbidden'; // Устанавливаем статус 403, доступ запрещен.
        cot_shield_update(7, "Log in"); // Обновляем защиту.
        cot_log("Pass recovery failed, user lostPass " . $v, 'users', 'passrecover', 'error'); // Логируем ошибку восстановления пароля.
        cot_redirect(cot_url('message', ['msg' => 151], '', true)); // Перенаправляем на страницу с сообщением об ошибке.
    }

    $user['user_id'] = (int) $user['user_id']; // Приводим ID пользователя к целочисленному типу.
    $user['user_maingrp'] = (int) $user['user_maingrp']; // Приводим ID основной группы пользователя к целочисленному типу.
    $user['user_banexpire'] = (int) $user['user_banexpire']; // Приводим время истечения бана пользователя к целочисленному типу.

    cot_fillGroupsForUser($user); // Заполняем группы пользователя.

    if (in_array(COT_GROUP_INACTIVE, $user['groups'], true)) { // Если пользователь в группе неактивных.
        cot_log( // Логируем ошибку восстановления пароля для неактивного пользователя.
            'Password recovery failed, user inactive: ' . $user['user_name'],
            'users',
            'passrecover', 'error'
        );
        $env['status'] = '403 Forbidden'; // Устанавливаем статус 403, доступ запрещен.
        cot_redirect(cot_url('message',  ['msg' => 152], '', true)); // Перенаправляем на страницу с сообщением, что пользователь неактивен.
    }

    if (in_array(COT_GROUP_BANNED, $user['groups'], true)) { // Если пользователь в группе забаненных.
        cot_log( // Логируем ошибку восстановления пароля для забаненного пользователя.
            'Password recovery failed, user banned: ' . $user['user_name'],
            'users',
            'passrecover',
            'error'
        );
        $env['status'] = '403 Forbidden'; // Устанавливаем статус 403, доступ запрещен.
        cot_redirect(cot_url('message', ['msg' => 153, 'num' => $user['user_banexpire']], '', true)); // Перенаправляем на страницу с сообщением, что пользователь забанен.
    }

    $validationKey = md5(microtime()); // Генерируем новый ключ для восстановления пароля.
    $newPassword = cot_randomstring(); // Генерируем новый случайный пароль.
    $updateData = [ // Подготавливаем данные для обновления пользователя в базе данных.
        'user_passsalt' => cot_unique(16), // Генерируем новый соль для пароля.
        'user_passfunc' => empty(Cot::$cfg['hashfunc']) ? 'sha256' : Cot::$cfg['hashfunc'], // Устанавливаем функцию хэширования для пароля.
        'user_lostpass' => $validationKey, // Обновляем ключ для восстановления.
    ];
    $updateData['user_password'] = cot_hash($newPassword, $updateData['user_passsalt'], $updateData['user_passfunc']); // Хэшируем новый пароль.

    Cot::$db->update(Cot::$db->users, $updateData, 'user_id = ?', $user['user_id']); // Обновляем данные пользователя в базе.

    $mailBody = Cot::$L['Hi'] . ' ' . UsersHelper::getInstance()->getFullName($user) . ",\n\n" // Формируем текст письма.
        . Cot::$L['pasrec_email2'] . "\n\n" . $newPassword . "\n\n" . Cot::$L['aut_contactadmin']; // Добавляем новый пароль и информацию о контакте с администратором.

    cot_mail($user['user_email'], Cot::$L['pasrec_title'], $mailBody); // Отправляем письмо с новым паролем пользователю.

    Cot::$sys['uri_redir'] = base64_encode(cot_url('index')); // Кодируем URL главной страницы для перенаправления после восстановления.

	$msg = 'auth'; // Устанавливаем статус для успешного восстановления пароля.
}

 

Cot::$out['subtitle'] = Cot::$L['pasrec_title']; // Устанавливаем подзаголовок страницы как название для восстановления пароля.
Cot::$out['head'] .= Cot::$R['code_noindex']; // Добавляем метатег noindex в head для запрета индексации этой страницы поисковыми системами.

$mskin = cot_tplfile('users.passrecover', 'module'); // Загружаем шаблон для восстановления пароля.

 /* === Hook === */
foreach (cot_getextplugins('users.passrecover.main') as $pl) { // Выполняем хуки для расширений на главной странице восстановления пароля.
	include $pl; // Включаем файл плагина.
}
/* ===== */

require_once Cot::$cfg['system_dir'] . '/header.php'; // Подключаем файл шапки сайта.

$t = new XTemplate($mskin); // Создаем объект XTemplate для работы с шаблоном.

$breadCrumbs = [ // Формируем хлебные крошки для страницы.
    [cot_url('users', ['m' => 'profile']), Cot::$L['pasrec_title']], // Крошка для ссылки на профиль.
];

$t->assign([ // Присваиваем переменные шаблону.
	'PASSRECOVER_TITLE' => Cot::$L['pasrec_title'], // Заголовок страницы восстановления пароля.
    'PASSRECOVER_BREADCRUMBS' => cot_breadcrumbs($breadCrumbs, Cot::$cfg['homebreadcrumb']), // Хлебные крошки.
	'PASSRECOVER_URL_FORM' => cot_url('users', ['m' => 'passrecover', 'a' => 'request']), // URL формы запроса на восстановление пароля.
]);

 /* === Hook === */
foreach (cot_getextplugins('users.passrecover.tags') as $pl) { // Выполняем хуки для расширений на странице с тегами.
	include $pl; // Включаем файл плагина.
}
/* ===== */

$t->parse('MAIN'); // Обрабатываем основной блок шаблона.
$t->out('MAIN'); // Выводим результат шаблона на страницу.

require_once Cot::$cfg['system_dir'] . '/footer.php'; // Подключаем файл подвала сайта.

 

11 минут чтения Sodium Carbonate

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

Комментарии отсутствуют
Добавление комментариев доступно только зарегистрированным пользователям

Автор контента

webitproff

Оффлайн

Sodium Carbonate

Последняя авторизация: 19.07.2026 01:57

  • Страница размещена: 31.01.2025 01:39
  • Последнее обновление: 31.01.2025 01:44

Похожие страницы

Модуль "Users", - users.passrecover.tpl в Cotonti CMF
1 Назначение шаблона users.passrecover.tpl Шаблон users.passrecover.tpl используется для отображения интерфейса страницы
Модуль "Users", - users.setup.php в Cotonti CMF
2 Файл users.setup.php в Cotonti CMF является конфигурационным файлом для модуля Users, который управляет регистрацией
Модуль "Users", - users.php в Cotonti CMF
3 Основное назначение файла и его место в системе Cotonti: Файл "users.php" в системе Cotonti является важным
Модуль "Users", - users.extrafields.php в Cotonti CMF
4 Основное назначение файла Файл users.extrafields.php в Cotonti CMF представляет собой часть модуля для управления
Модуль "Users", - users.admin.home.php в Cotonti CMF
5 Основное назначение файла "users.admin.home.php" в системе Cotonti — это обработка административной панели