Модуль "Users", - users.passrecover.php в Cotonti CMF
предназначен для обработки процесса восстановления пароля пользователя. Он играет важную роль в механизме аутентификации и восстановления доступа к учетной записи
Общее описание файла "users.passrecover.php"
Файл "users.passrecover.php" в системе Cotonti CMF предназначен для обработки процесса восстановления пароля пользователя. Он играет важную роль в механизме аутентификации и восстановления доступа к учетной записи на сайте. Этот файл размещен в директории /modules/users/inc, что указывает на его принадлежность к модулю пользователей, отвечающему за управление профилями и аутентификацию пользователей.
Основное назначение файла и его место в системе Cotonti
Назначение:
- Главной задачей данного файла является обработка запросов на восстановление пароля пользователей. Когда пользователь забывает свой пароль, этот файл помогает ему вернуть доступ к учетной записи путем отправки инструкции по восстановлению на его электронную почту или непосредственно сброса пароля с помощью проверочного кода.
Место в системе:
- Этот файл является частью модуля "users" в рамках системы управления пользователями и связан с функционалом восстановления паролей. Он работает в связке с другими модулями сайта, такими как обработка форм, отправка сообщений по электронной почте, а также с системой безопасности.
Взаимодействие с другими частями системы
Файл взаимодействует с несколькими компонентами системы Cotonti:
- База данных – запросы к базе данных выполняются для получения информации о пользователе по его электронной почте, а также для обновления данных о пользователе после сброса пароля.
- Система безопасности – используются функции для защиты от атак типа CSRF (например, через вызовы
cot_shield_protect()). - Система отправки почты – отправляются электронные письма с инструкциями по восстановлению пароля.
- Шаблонная система – используется для вывода интерфейса для восстановления пароля (например, через создание и вывод шаблона с помощью XTemplate).
Основные используемые переменные, методы, функции, классы
$a– Параметр запроса, определяющий текущую операцию: может быть значением'request'или'auth'.$email– Электронная почта пользователя, передаваемая в запросе для поиска соответствующего пользователя в базе данных.$v– Код, связанный с восстановлением пароля (например, проверочный ключ).$msg– Сообщение статуса восстановления пароля.Cot::$usr['id']– ID текущего пользователя (используется для проверки, не является ли пользователь авторизованным).Cot::$db– Объект для работы с базой данных (выполняет запросы на получение и обновление данных пользователей).cot_shield_protect()– Функция защиты от атак CSRF, используется для предотвращения подделки запросов.cot_shield_update()– Функция для обновления информации о защите (например, обновление токена безопасности).cot_log()– Функция для записи логов с определенным уровнем серьезности (например, при ошибках восстановления пароля).cot_redirect()– Функция для перенаправления пользователя на другую страницу.cot_mail()– Функция для отправки электронной почты пользователю.Cot::$cfg– Конфигурация системы, которая используется для получения настроек сайта.Cot::$L– Локализация текста для вывода сообщений на разных языках.Cot::$R– Ресурсы системы, например, код для запрета индексации страницы поисковиками.XTemplate– Класс для работы с шаблонами и выводом HTML-кода.UsersHelper::getFullName()– Метод для получения полного имени пользователя.
Суть содержания кода
Файл "users.passrecover.php" состоит из нескольких блоков, каждый из которых выполняет конкретную задачу:
-
Запрос на восстановление пароля (a = 'request'):
- Проверяется, была ли введена электронная почта.
- Выполняется поиск пользователя по введенному email в базе данных.
- Если пользователя с таким email нет, выводится ошибка.
- Если пользователь найден, для него генерируется уникальный ключ восстановления пароля, который сохраняется в базе данных.
- Пользователю отправляется email с ссылкой на страницу для изменения пароля.
- Если пользователю отправлено письмо, он перенаправляется на страницу с подтверждением.
-
Аутентификация по ссылке восстановления пароля (a = 'auth'):
- Проверяется валидность кода восстановления.
- Если код не найден или неверен, происходит редирект на страницу с ошибкой.
- Если код верный, генерируется новый пароль для пользователя и обновляются его данные в базе данных.
- Пользователю отправляется письмо с новым паролем.
-
Отображение страницы восстановления пароля:
- Формируется шаблон страницы, который выводит форму для запроса на восстановление пароля.
- Используются хуки для расширяемости, позволяя подключать дополнительные модули или функционал.
Возможности для владельца сайта
Владелец сайта может использовать этот сценарий для обеспечения пользователей возможностью восстановить доступ к их учетным записям в случае потери пароля. Процесс включает:
- Введение электронной почты для получения инструкции по восстановлению.
- Введение проверочного кода для сброса пароля.
- Генерацию нового пароля и отправку его пользователю.
Также, используя хуки, можно легко расширять или изменять поведение этой системы для нужд конкретного сайта.
Стиль написания 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'; // Подключаем файл подвала сайта.
Комментарии (0)
Автор контента
Оффлайн
Sodium Carbonate
Последняя авторизация: 19.07.2026 01:57
- Страница размещена: 31.01.2025 01:39
- Последнее обновление: 31.01.2025 01:44