Срок действия учетных данных SSO / принудительный выход из системы

Какое время действия сессии пользователя я могу ожидать до повторного запроса входа?

Я реализовал собственную проверку в functions.php, интегрировав её с плагином SSO для WordPress. Логика кажется довольно простой, но я заметил, что пользователь, у которого была отклонена банковская карта (из-за чего был снят тег пользователя, проверяемый моей логикой), сегодня смог получить доступ к моему форуму. При дальнейшей проверке выяснилось, что она последний раз входила в систему несколько дней назад и, похоже, всё ещё считается вошедшей. Дата её последнего входа в WordPress также была несколько дней назад.

Ожидается ли, что её кэшированные учётные данные всё ещё будут работать? Если да, существует ли способ контролировать срок действия токена и/или реагировать на webhook для принудительного выхода из системы?

Спасибо.

Это контролируется настройкой сайта Discourse «maximum session age» (максимальный возраст сессии). Она определяет количество часов, в течение которых пользователи остаются авторизованными на вашем сайте. По умолчанию установлено значение 1440 часов (60 дней). Вы можете попробовать установить меньшее значение. Если вы установите его слишком низким, это может показаться пользователям ошибкой.

Это логично. Вы можете вручную разлогинить пользователей, перейдя на страницу администратора Discourse и нажав кнопку «Log Out» (Выйти), которая находится в правом верхнем углу страницы. Другой вариант контроля — добавить код на ваш сайт WordPress, который будет автоматически разлогинивать пользователей из Discourse при истечении срока их членства.

Большое спасибо, Саймон. Хотя я считаю, что 60 дней — это слишком долго для моих сценариев (это платные участники, и они ожидают, что мы будем проверять, что они всё ещё действительные участники), я согласен, что слишком сильное сокращение этого срока может создать неудобства.

Последнее предложение (найти способ автоматически выводить участников из системы Discourse, когда членство заканчивается) — это то, что я буду изучать. Я видел опцию ручного выхода, но поскольку я стремлюсь полностью автоматизировать весь процесс, это кажется правильным путём.

Спасибо ещё раз.

Хм… в описании этой настройки сайта сказано (выделение моё):

Пользователь будет оставаться авторизованным в течение n часов с момента последнего посещения

Если я правильно понимаю, пользователь может оставаться авторизованным бесконечно, если он продолжает посещать сайт периодически, даже после утраты учётных данных SSO. Например, если настройка установлена на 72 часа, то при условии посещения сайта каждые один-два дня он будет оставаться авторизованным. Правильно ли я трактую это?

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

Получается ли, что если кто-то отменит мою подписку, а я хочу быть уверен, что у него больше нет доступа к моему форуму, мне придётся принудительно разлогинить его (вручную или через вызов API)?

Да, это рекомендация.

Спасибо. Только что перешёл с группы Facebook (где приходилось вручную удалять участников при отмене их подписки), и, к сожалению, в Discourse мне всё равно придётся вручную следить за тем, чтобы отменившие подписку не имели доступа к форуму. Это поднимает вопрос.

Существует ли какой-либо не ручной механизм — какой бы креативный он ни был — который гарантировал бы, что пользователь без действующего аккаунта (то есть не способный войти в систему) будет принудительно разлогинен в Discourse?

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

Думаю, мой последний вариант — возможно, написать плагин, который будет вызывать API Discourse для разлогинивания пользователя при отмене подписки.

Открыт ко всем идеям. Как вы можете заметить, я ОЧЕНЬ хочу избежать ручной работы :slight_smile:

Спасибо.

Вы можете отправить API-запрос к /admin/users/<discourse_user_id>/log_out. Плагин WP Discourse использует этот маршрут для синхронизации выхода из WordPress с Discourse. Скорее всего, вы сможете скопировать большую часть кода из этой функции: wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub.

Большое спасибо, Саймон. Я обязательно посмотрю.

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

Возможно, я согласен с тем, что авторитетным источником здесь является WordPress, а не Discourse. Это, вероятно, указывает на то, что логика должна быть размещена в плагине SSO.

Мне интересно узнать общую точку зрения здесь. Я бы хотел думать, что такой сценарий является валидным (принудительный выход из системы через определенный период времени или при «недействительности» аккаунта WordPress), не так ли?

Просто размышляю вслух, так как хотел бы избежать ручных шагов, но также хочу избежать написания кода, если это возможно :slight_smile:

Да, это должно обрабатываться на стороне WordPress. Мне кажется логичным, чтобы плагин WP Discourse разлогивал пользователей из Discourse, когда они удаляются в WordPress, но я не уверен, что это решит вашу проблему. Я исхожу из того, что когда членство пользователя истекает на вашем сайте, пользователь не удаляется из вашего сайта на WordPress. Чтобы обработать случай разлогивания пользователя из Discourse при истечении членства, вам, вероятно, потребуется добавить некоторый код на ваш сайт, который будет взаимодействовать с действием, запускаемым вашим плагином управления членством при истечении членства.

Ещё раз спасибо, @simon. Ваши аргументы убедительны, но позвольте мне добавить ещё одну мысль :slight_smile:

Похоже, здесь задействованы два фактора: действительность учётной записи (а именно, является ли пользователь активным участником) и действительность токена в Discourse.

В первом случае я полностью согласен, что WordPress должен отвечать за это, и, как только появится время, я изучу этот вопрос.

Однако также стоит рассмотреть вопрос о действительности токена на стороне Discourse. Понимаю, что это может быть не приоритетной задачей, но вижу логику в опции (вероятно, по умолчанию отключённой), которая устанавливает срок действия принудительного входа: то есть через x дней токен входа пользователя истекает, независимо от того, заходил ли он недавно.

Снова скажу, что я просто генерирую идеи, но вижу определённую ценность в возможности принудительного выхода из системы как опции, независимо от того, действительна ли учётная запись пользователя.

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

https://community.mysite.com/admin/users/100004/log_out

У меня возникает ошибка 404, и пользователь не выходит из системы.

Если мне удастся заставить URL работать, я надеюсь принудительно выйти из системы, используя команду curl или file_get_contents в PHP…

Вам нужно отправить аутентифицированный POST-запрос к маршруту. Вы можете настроить это так, чтобы при клике на ссылку пользователи выходили из системы, но обработку запроса придётся реализовать на стороне сервера.

Спасибо! Вы авторизованы, да? Проводя исследование, я обнаружил, что авторизованный пост из PHP отправляет что-то вроде этого в заголовке:

'Authorization: OAuth '.$accesstoken;

Есть несколько подсказок, которые я продолжу изучать.

Но было бы здорово, если бы у кого-то был рабочий фрагмент кода на PHP! Пример в разделе аутентификации на https://docs.discourse.org/ выдаёт ошибку синтаксиса… ой, подождите, это команда Unix!

Буду рад любым подсказкам, которые помогут с PHP!

Ссылка из моего предыдущего сообщения должна быть достаточной, чтобы вы могли начать: wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub. Предполагая, что вы делаете запрос не с сайта WordPress, вам нужно будет найти другой способ выполнить запрос wp_remote_post.

Думаю, я почти у цели, используя простые команды PHP. Код ниже. Выбор имени пользователя основан на этом посте.

Я получаю такой ответ… это что-то значит для кого-нибудь? Похоже на проблему с версией протокола SSL?

error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

Вот мой код:

    $url = "https://community.mysite.com/admin/users/100004/log_out";
    $headers = array( 'Api-Key' => 'd412mylongadminkeyaadcd',
                    'Api-Username' => 'system',
                    );

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);

[edit: добавил эти строки тоже, без изменений:]
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
[/edit]

	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $data = curl_exec($ch);
    if (curl_errno($ch)) {
        echo curl_error($ch);
    }
    curl_close($ch);

Поскольку вы используете WordPress, попробуйте выполнить запрос с помощью функции wp_remote_post. Так вам не придётся разбираться с опциями curl.

Спасибо, но я не использую WordPress. Я пытаюсь реализовать это на PHP в собственном менеджере членства, который я разрабатывал на протяжении последнего десятилетия.

Похоже, ваша библиотека PHP не приняла HTTPS-сертификат вашего Discourse. Попробуйте поискать эту ошибку в Google.