Привет, у меня возникла проблема с SSO в Discourse. Что я делаю не так? Мой код ниже без проблем извлекает данные с другой платформы, но nonce не приходит.
<?php
// Включить логирование ошибок для отладки
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Загрузить файл инициализации
require_once '/init.php'; // Обновите этот путь в зависимости от настроек вашей платформы
// Секретный ключ Discourse Connect и URL для возврата полезной нагрузки
$sso_secret = 'keyhere'; // Замените на ваш общий секретный ключ Discourse
$discourse_url = 'https://urlhere.com/session/sso_login'; // Замените на ваш URL Discourse
// Запустить сессию для проверки состояния входа пользователя на платформе
session_start();
// Проверить, вошел ли пользователь в систему
if (!isset($_SESSION['uid'])) {
// Если пользователь не вошел, перенаправить на страницу входа на платформу
header('Location: /clientarea.php');
exit;
}
// Отладка: записать входящие параметры запроса
error_log("Получены параметры GET: " . print_r($_GET, true));
// Проверить, получены ли параметры 'sso' и 'sig' от Discourse
if (!isset($_GET['sso']) || !isset($_GET['sig'])) {
error_log("Отсутствуют параметры SSO или SIG.");
header('Location: /clientarea.php');
exit;
}
// Проверить подпись SSO с помощью секретного ключа
$sso = $_GET['sso'];
$sig = $_GET['sig'];
$expected_sig = hash_hmac('sha256', $sso, $sso_secret);
if ($sig !== $expected_sig) {
error_log("Неверная подпись SSO. Ожидалось: $expected_sig, Получено: $sig");
header('Location: /clientarea.php');
exit;
}
// Получить данные клиента платформы
$clientDetails = localAPI('getclientsdetails', ['clientid' => $_SESSION['uid']], 'admin');
if ($clientDetails['result'] !== 'success' || !isset($clientDetails['userid'])) {
error_log("Не удалось получить данные клиента платформы.");
header('Location: /clientarea.php');
exit;
}
// Извлечь данные пользователя
$userId = $clientDetails['userid'];
$email = $clientDetails['email'];
$firstName = $clientDetails['firstname'];
$lastName = $clientDetails['lastname'];
$username = $firstName . ' ' . $lastName;
// Декодировать полезную нагрузку SSO
$sso_payload = base64_decode($sso);
parse_str($sso_payload, $sso_params);
if (!isset($sso_params['nonce'])) {
error_log("Nonce отсутствует в полезной нагрузке SSO.");
header('Location: /clientarea.php');
exit;
}
// Подготовить возвращаемую полезную нагрузку SSO с данными пользователя
$return_payload = [
'nonce' => $sso_params['nonce'],
'email' => $email,
'external_id' => $userId,
'username' => $username,
'name' => $firstName . ' ' . $lastName,
'admin' => 0, // Установите 1, если пользователь является администратором, иначе оставьте 0
'moderator' => 0 // Установите 1, если пользователь является модератором, иначе оставьте 0
];
// Закодировать возвращаемую полезную нагрузку в base64
$query_string = http_build_query($return_payload);
$encoded_payload = base64_encode($query_string);
// Подписать закодированную полезную нагрузку секретным ключом Discourse
$return_sig = hash_hmac('sha256', $encoded_payload, $sso_secret);
// Отладка: записать полезную нагрузку и подпись
error_log("Возвращаемая полезная нагрузка: " . print_r($return_payload, true));
error_log("Закодированная полезная нагрузка: $encoded_payload");
error_log("Возвращаемая подпись: $return_sig");
// Перенаправить в Discourse с подписанной полезной нагрузкой
header("Location: $discourse_url?sso=" . urlencode($encoded_payload) . "&sig=" . urlencode($return_sig));
exit;
Логи ошибок:
[25-сен-2024 14:50:17 UTC] Отсутствуют параметры SSO или SIG.
[25-сен-2024 14:53:59 UTC] Получены параметры GET: Массив
(
[sso] => nonce_from_discourse
)
[25-сен-2024 14:53:59 UTC] Отсутствуют параметры SSO или SIG.
Непонятно, почему так?"}

