Сбой соединения DC SSO замедляет работу администратора из-за тайм-аута

Я настроил SSO Discourse Connect с использованием официального плагина, поэтому пользователи WordPress входят в Discourse без необходимости регистрации нового аккаунта там. Всё работает отлично, за исключением того, что каждый запрос к панели управления WordPress (админ-панель) замедляется на 10 секунд из-за тайм-аута, который я обнаружил только с помощью плагина Query Monitor.

https://{our-forum-address}/site.json cURL ошибка 28: Превышено время ожидания соединения после 10001 мс

WPDiscourse\Admin\MetaBox->discourse_request()
wp-content/plugins/wp-discourse/lib/plugin-utilities.php:516
WPDiscourse\Admin\MetaBox->get_discourse_categories()
wp-content/plugins/wp-discourse/lib/plugin-utilities.php:273
WPDiscourse\Admin\MetaBox->setup_options()
wp-content/plugins/wp-discourse/admin/meta-box.php:49
do_action('admin_init')
wp-includes/plugin.php:517

Плагин: wp-discourse

Даже если бы это работало, зачем вообще нужен такой вызов? Как я могу его отключить?

Форум и сайт находятся на разных серверах. Cloudflare отсутствует. SSL настроен через Let’s Encrypt. На тестовом окружении этой проблемы не было. Я переехал на боевой сервер, создал новый API-ключ и секрет, пытаясь решить проблему, но это не помогло.

Плагин пишет: Вы не подключены к Discourse. Проверьте правильность настроек подключения. Если проблема сохраняется, включите журналы подключения и проверьте их. …но я подключён, так как пользователи могут беспрепятственно входить на форум, просто перейдя по ссылке с его адресом.

В логах WordPress сказано:


[2024-10-31 10:54:47] connection.INFO: check_connection_status.failed_to_connect {"error":"wpdc_response_error","message":"От Discourse получен недопустимый ответ","http_code":"","http_body":""}

Я думал, что какая-то странная функция безопасности WordPress ограничивает работу, поэтому добавил этот код, но это тоже не помогло:


add_filter('http_request_host_is_external', [$this, 'mark_discourse_api_url_external'], 10, 3);

function mark_discourse_api_url_external($is_external, $host, $url)
{
	if ($host === "{our-forum-address}") {
		return true; // Разрешить запрос, указав, что хост является внешним
	}

	return $is_external;
}

Привет, @Firsh,

Этот вызов к вашему /site.json необходим для плагина WordPress, чтобы получить информацию о вашем Discourse.

Это означает, что вы не подключены должным образом, и даже если всё кажется работающим, я бы не рассчитывал на то, что это продолжит работать.

На этом нам и нужно сосредоточиться. Не могли бы вы уточнить, какой тип ключа вы создали? Для справки убедитесь, что вы следуете рекомендациям по этому вопросу здесь:

Думаю, дело не в ключе. Я заранее пробовал с ключом тестового сайта, а новый показывает сообщение «никогда не использовался». Когда я пытаюсь выполнить тестовый вызов wp_remote_request к главной странице моего форума, это также приводит к тайм-ауту. Я настроил это для «всех пользователей» и «глобально».

Да, но зачем это делать постоянно на каждой не связанной странице администратора? Достаточно было бы один раз, когда это действительно нужно. Я выяснил, откуда это исходит: это функция get_discourse_categories(), и она жёстко прописана в add_action( ‘admin_init’, array( $this, ‘setup_options’ ) );. Мне не нужно, чтобы мой WordPress знал о категориях на форуме, я не использую функции публикации или комментирования, мне нужен только вход, который уже работает.

Я также отправил запрос к главной странице форума с помощью wp_remote_request(), и он тоже завершился тайм-аутом. Другие случайные сайты доступны.

Я понимаю, что вы считаете запрос к /site.json ненужным, однако без успешного подключения к вашему Discourse плагин WordPress не будет работать надежно, поэтому нам нужно выяснить, почему это не работает.

  1. Можете ли вы вспомнить какие-либо другие различия между вашей тестовой и рабочей средой?
  2. Можете ли вы предоставить файлы логов метаданных WP Discourse для ваших тестовой и рабочей инстанций?
  3. Можете ли вы предоставить ссылки на ваши экземпляры WordPress и Discourse?

Да, но это закрытый сайт и форум только для участников на венгерском языке.

Форум: https://forum.intelligensbefektetok.hu/
Сайт: https://intelligensbefektetok.hu/

Моя тестовая среда (staging) была точной ручной копией, работающей в Docker на виртуальной машине. Продуктивная среда (prod) не находится под моим управлением; я не знаю, какой именно хостинг используется, но раньше у нас никогда не было проблем, и всё работало довольно быстро.

Только что я попробовал следующее:

  • Опцию sslverify = false в функции discourse_request.
  • Создал CNAME (алиас) на Cloudflare на одном из моих других доменов, чтобы перенаправлять запросы на хост форума «за кулисами» (это обеспечило «лучший» SSL и использование другого хоста, чтобы исключить возможные ограничения loopback в фаерволе хостинга продуктивного сайта): https://ibkforum.stateofbliss.us. Однако запросы всё равно завершаются тайм-аутом так же, как и раньше, хотя тестовые запросы со staging-среды работают без проблем. При этом, если пользователь не авторизован, происходит перенаправление на основной сайт.
  • Я использую этот небольшой плагин для проверки запросов: https://wphive.com/plugins/wp-remote-request-check/

object(WP_Error)#5757 (3) { [“errors”]=> array(1) { [“http_request_failed”]=> array(1) { [0]=> string(59) “cURL error 28: Connection timed out after 5000 milliseconds” } } [“error_data”]=> array(0) { } [“additional_data”:protected]=> array(0) { } }

  • Другие сайты на WordPress, этот форум и продуктивный сайт при выполнении запросов к самому себе — всё работает корректно.

Логи WordPress на staging-среде:

[2024-10-31 13:09:08] connection.INFO: check_connection_status.valid_scopes  
[2024-10-31 13:09:19] connection.INFO: check_connection_status.successful_connection  
[2024-10-31 13:09:19] connection.INFO: check_connection_status.valid_scopes

Логи продуктивного сайта такие же, как в моём первоначальном сообщении:

[2024-10-31 13:12:32] connection.INFO: check_connection_status.failed_to_connect {"error":"wpdc_response_error","message":"An invalid response was returned from Discourse","http_code":"","http_body":""}

При прямом открытии в браузере это работает:
https://forum.intelligensbefektetok.hu/site.json

Спасибо за помощь, кстати.

Вы имеете в виду продакшн-окружение WordPress или Discourse? Возможно, в вашем окружении Discourse что-то выполняет перенаправления и/или изменяет (или удаляет) заголовки в запросах?

Если вы сможете предоставить эти файлы meta для обоих окружений, это поможет. Нажмите «Просмотреть meta» в админ-панели «Логи».

Это, вероятно, основная проблема. Если ваш WordPress вообще не может увидеть ваш Discourse, соединение не будет работать. Если вы можете легко проверить эту связность, продолжайте делать это, одновременно внося изменения в сетевой уровень вашего форума, пока не получите ответ 403 (т. е. «не авторизован»).

Мне кажется, что это проблема сетевого уровня, возможно, связанная с перенаправлением или фаерволом.

У нас нет отдельного тестового (staging) форума Discourse — оба сайта используют один и тот же рабочий форум (одинаковые ID пользователей и т.д.). Я уже задавал этот вопрос в другой ветке, и там сказали, что всё должно работать. Сетевой уровень форума очень простой: хостинг на Hetzner, официальный Docker-контейнер на VPS. Форум практически не использовался и не настраивался, кроме некоторых визуальных изменений. Мне неизвестны какие-либо настройки, которые могли бы препятствовать доступу к нему. Я создал тикет в компании, предоставляющей хостинг для WordPress, чтобы они проверили, почему соединения не устанавливаются, так как меня больше беспокоит их нестандартная конфигурация.

Для меня интересно, что самого факта, что форум может обращаться к WordPress (но не наоборот), «достаточно» для работы SSO. За исключением выхода пользователей из форума.

Логи (на рабочем сайте скачивается ZIP-архив размером 0 байт).

Да, я бы сначала подождал результатов, иначе мы можем просто крутиться на месте. Основной вопрос: почему стандартный запрос WP не может достичь вашего форума.