Вопрос или проблема
Я недавно создал частный сайт Managed WordPress от godaddy с BuddyPress, используя плагин Force Login, чтобы сделать его закрытым для 20 или около того жильцов на конеферме. Я также установил плагин The Events Calendar, чтобы предоставить календарь, который поддерживается владельцем конюшни, чтобы все могли видеть, когда подойдут кузнецы, ветеринары, тренеры и клиницисты. Все работает хорошо, кроме того, что:
Страница /events, которая встроена в The Events Calendar, имеет хорошую функцию поиска событий, а также изменения вывода, чтобы показывать события в виде списка или в течение одного месяца или дня. Но когда нажимаешь на любую из кнопок Поиск, Список, Месяц или День, ничего не происходит. Используя инструменты разработчика Chrome, я вижу, что проблема заключается в том, что нажатие на любую из этих кнопок вызывает ответ 403 на XMLHttpRequest, отправленный плагином на конечную точку REST в плагине. Я проверил, что деактивация плагина Force Login устраняет 403 и позволяет этим кнопкам вести себя ожидаемым образом.
Я не знаком с использованием REST APIs и довольно долго не занимался кодированием, но моя первая реакция заключалась в том, чтобы отредактировать исходный код плагина, добавив “withCredentials = true;” в объект запроса XHR перед его отправкой, думая, что проблема, очевидно, в том, что ajax-запрос не указывает, что контекст запроса авторизован в WordPress. Это не решило проблему, и в ходе некоторых исследований я нашел статью, объясняющую, что поле withCredentials не имеет эффекта на запрос с того же источника, что и этот.
Я попросил помощи на форуме поддержки плагина, но не пришел к успеху, потому что, чтобы воспроизвести это, нужно быть авторизованным на сайте, а форум поддержки не позволяет отправлять учетные данные для входа на сайт. Они смогли только сказать, что это проблема, вызванная плагином Force Login, и что я должен обратиться в поддержку этого плагина.
Возможно, это так, и я свяжусь со службой поддержки Force Login, но у меня есть предчувствие, что проблема должна быть в коде The Events Calendar, который каким-то образом не успевает передать авторизованный контекст на вызываемую конечную точку.
Какие-либо предложения?
** РЕДАКТИРОВАНИЕ **
В форме, написанной выше, этот вопрос был закрыт как не по теме, очевидно, потому что он был интерпретирован как вопрос о конкретных плагинах, которые не по теме здесь, и лучше задавать на форуме поддержки плагина. Что ж, я изначально спрашивал на форуме поддержки плагина The Events Calendar и получил ответ стандартного типа, что, поскольку деактивация плагина Force Login решает проблему, то это не проблема плагина The Events Calendar, а скорее проблема с Force Login, так что мне следует обратиться в поддержку Force Login. Я могу и обязательно сделаю это; но, немного углубившись в проблему, мне кажется, что это пример общей проблемы при кодировании плагинов для WordPress: как плагин должен делать Ajax-запросы, чтобы вызываемая функция видела правильное состояние входа от вызывающего объекта. И это и послужило причиной, по которой я разместил это здесь.
Насколько я могу судить, плагин Force Login правильно проверяет, есть ли пользователь WordPress, вошедший в систему, и если нет, то выдает код состояния 403 и переходит на страницу входа. Таким образом, проблема, похоже, заключается в том, что способ, которым The Events Calendar выполняет Ajax-запрос, не предоставляет состояние входа для цели вызова (которая оказывается конечной точкой REST внутри The Events Calendar). Поэтому я изменил название этого вопроса, чтобы более точно отразить общую природу вопроса для WordPress и убрал из названия названия конкретных плагинов, участвующих в этом случае, но оставил оригинальную информацию о конкретных плагинах для справки, так как они оба довольно популярны. Я надеюсь, что это устроит модераторов, потому что я считаю, что хороший ответ здесь будет полезен многим другим разработчикам плагинов (а также разработчикам The Events Calendar).
Ответ или решение
Вопрос о том, как плагин может выполнить Ajax-запрос (XMLHttpRequest) к REST API с правильной и надежной передачей текущего состояния входа пользователя в WordPress, представляет собой актуальную проблему для разработчиков. Данное руководство предоставит вам всесторонний анализ этого процесса, с учетом особенностей работы WordPress и использования REST API.
1. Понимание проблемы
В вашем случае, плагин The Events Calendar сталкивается с ответом 403 при попытке выполнения Ajax-запросов к своему REST API, когда активирован плагин Force Login. Ответ 403 указывает на то, что запрос был отклонен из-за недостатка прав доступа, что часто происходит, когда механизм авторизации не может подтвердить, что пользователь вошел в систему.
2. Основы работы с REST API в WordPress
REST API в WordPress использует механизм для проверки прав доступа и аутентификации пользователей. По умолчанию WordPress проверяет, прошла ли аутентификация, и предоставляет доступ к определенным точкам API в зависимости от ролей и прав, назначенных пользователю.
3. Передача состояния входа через Ajax-запрос
Для выполнения Ajax-запросов от вашего плагина к REST API необходимо передавать правильные заголовки, которые сигнализируют о состоянии аутентификации. Ниже представлены основные шаги:
Шаг 1: Использование wp_localize_script
Для начала вам нужно передать текущую аутентификацию WordPress в скрипт вашего плагина. Это можно сделать с помощью функции wp_localize_script
, что позволит вам добавить данные к вашему JavaScript-коду:
function my_plugin_enqueue_scripts() {
wp_enqueue_script('my-plugin-script', plugin_dir_url(__FILE__) . 'js/my-script.js', array('jquery'), '1.0', true);
// Добавление переменной для AJAX URL
wp_localize_script('my-plugin-script', 'myAjax', array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('my_nonce') // Создание nonce
));
}
add_action('wp_enqueue_scripts', 'my_plugin_enqueue_scripts');
Шаг 2: Создание Ajax-запроса
При отправке Ajax-запроса важно указать созданный вами nonce для проверки. В JavaScript коде можно использовать следующий пример:
jQuery(document).ready(function($) {
$('#my-button').click(function() {
$.ajax({
url: myAjax.ajaxurl,
method: 'POST',
data: {
action: 'my_action', // название вашего действия
nonce: myAjax.nonce, // добавление nonce
// другие данные
},
success: function(response) {
console.log(response);
},
error: function(xhr) {
console.error(xhr.responseText);
}
});
});
});
Шаг 3: Обработка запроса на сервере
На сервере необходимо обработать этот запрос и проверить nonce:
function my_ajax_handler() {
check_ajax_referer('my_nonce', 'nonce'); // Проверка nonce
// Код обработки запроса
wp_send_json_success('Данные успешно получены');
}
add_action('wp_ajax_my_action', 'my_ajax_handler');
4. Проверка состояния пользователя
Если вы хотите убедиться, что текущий пользователь имеет права для выполнения определенного действия, вы можете использовать функцию current_user_can()
в обработчике Ajax:
if (!is_user_logged_in() || !current_user_can('desired_capability')) {
wp_send_json_error('Доступ запрещен', 403);
}
Заключение
Чтобы обеспечить надежную передачу состояния входа пользователя через Ajax-запрос к REST API, необходимо использовать корректные методы аутентификации и авторизации, такие как nonce. Применение описанных шагов поможет избежать ошибок 403 и обеспечит стабильную работу вашего плагина в условиях, когда активированы другие плагины, такие как Force Login.
Эти рекомендации не только помогут вам решить текущую проблему, но и обеспечат лучший опыт взаимодействия с API для ваших пользователей.