Диагностика проблемы: почему нужно ограничивать доступ к тикетам
В системах поддержки на WordPress с плагином WPtickets часто возникает задача обеспечить, чтобы пользователи видели только свои тикеты, а агенты — только относящиеся к ним. Без правильной настройки доступа можно столкнуться с ситуацией, когда любой зарегистрированный пользователь получает доступ к чужим обращениям, что нарушает безопасность и конфиденциальность.
Проверьте текущие настройки доступа, выполнив следующие шаги:
- Авторизуйтесь под тестовым пользователем, создав несколько тикетов;
- Попробуйте просмотреть список тикетов другого пользователя;
- Если видите чужие тикеты, значит ограничения не работают.
Также полезно проверить, нет ли конфликтов с другими плагинами, которые могут переопределять права доступа.
Как ограничить доступ к тикетам в WPtickets с помощью capabilities
WPtickets по умолчанию использует стандартные роли WordPress, но для тонкой настройки доступа нужно подключить механизм capabilities. Мы создадим кастомные права и добавим проверки в шаблоны и REST API запросы.
1. Создание пользовательской capability
Добавьте следующий код в файл functions.php вашей темы или в отдельный плагин:
function wptickets_add_custom_capabilities() {
$role = get_role('agent'); // или другая роль, которая обрабатывает тикеты
if (!$role->has_cap('view_all_tickets')) {
$role->add_cap('view_all_tickets');
}
}
add_action('init', 'wptickets_add_custom_capabilities');Это добавит право view_all_tickets роли агента. Теперь добавим проверку для отображения тикетов.
2. Фильтрация отображаемых тикетов
Чтобы пользователи без права view_all_tickets видели только свои тикеты, используйте следующий фильтр, модифицирующий запрос:
function wptickets_filter_tickets_by_user($query) {
if (!is_admin() && is_post_type_archive('wpticket')) {
if (!current_user_can('view_all_tickets')) {
$query->set('author', get_current_user_id());
}
}
}
add_action('pre_get_posts', 'wptickets_filter_tickets_by_user');Этот код гарантирует, что на фронтенде (не в админке) пользователи видят только свои тикеты, а агенты с правом view_all_tickets — все.
3. Контроль доступа в REST API (если используется)
Если ваша система использует REST API для работы с тикетами, необходимо ограничить доступ там:
add_filter('rest_wpticket_query', function($args, $request) {
if (!current_user_can('view_all_tickets')) {
$args['author'] = get_current_user_id();
}
return $args;
}, 10, 2);Этот фильтр ограничит REST запросы тикетов текущим пользователем, если у него нет права на просмотр всех.
Пошаговое руководство по настройке ограничения доступа
- Добавьте capability для роли агента, как указано выше.
- Внедрите фильтр
pre_get_postsвfunctions.phpдля ограничения видимости в списках. - Если используете REST API, добавьте фильтр для ограничения запросов.
- Проверьте роли пользователей и назначьте нужные права в админке WordPress (через плагин User Role Editor или кодом).
- Очистите кэш сайта и браузера.
- Протестируйте под разными пользователями.
Проверка результата после внедрения
- Залогиньтесь под обычным пользователем и убедитесь, что он видит только свои тикеты.
- Залогиньтесь под агентом (роль с capability
view_all_tickets) и проверьте, что отображаются все тикеты. - Попробуйте получить список тикетов через REST API с разных ролей и убедитесь, что фильтрация работает.
- Проверьте, что в админке нет доступа к чужим тикетам у пользователей без права
view_all_tickets.
Частые ошибки и как их исправить
- Ошибка: Фильтр
pre_get_postsне срабатывает.
Причина: Возможно, запрос не является основным или не для типаwpticket. Проверьте условиеis_post_type_archive('wpticket')или используйтеis_post_type_archive()иis_main_query(). - Ошибка: Пользователи видят чужие тикеты в админке.
Решение: Добавьте фильтрацию запросов и для админки, например:
function wptickets_filter_admin_tickets($query) {
if (is_admin() && $query->is_main_query() && $query->get('post_type') === 'wpticket') {
if (!current_user_can('view_all_tickets')) {
$query->set('author', get_current_user_id());
}
}
}
add_action('pre_get_posts', 'wptickets_filter_admin_tickets');- Ошибка: REST API возвращает все тикеты.
Решение: Добавьте фильтр для REST запросов, как показано выше.
Практические советы по безопасности и производительности
- Используйте capability вместо прямой проверки ролей — это гибче и масштабируемо.
- Проверяйте пользовательские запросы на стороне сервера, не доверяйте только фронтенду.
- Оптимизируйте запросы фильтрации по автору с индексами в базе данных для быстрого отклика.
- Регулярно обновляйте WPtickets и WordPress, чтобы избежать уязвимостей.
- Если у вас большой сайт с сотнями агентов и тысячами тикетов, рассмотрите кэширование результатов с ключом по пользователю и роли.
Сравнение вариантов ограничения доступа к тикетам
| Метод | Плюсы | Минусы |
|---|---|---|
| Фильтрация по author в pre_get_posts | Просто реализуется, работает на фронтенде и в админке | Нужно корректно проверять условия, чтобы не закрыть доступ агентам |
| Capability «view_all_tickets» | Гибкая настройка прав, легко расширять | Требует ручного назначения прав ролям |
| Фильтрация REST API запросов | Обеспечивает безопасность для AJAX и API | Нужно учитывать все конечные точки API |