Hola, tengo un problema con Discourse SSO. ¿Qué estoy haciendo mal? Mi código extrae de mi otra plataforma sin ningún problema. Sin embargo, no recibo ningún nonce.
// Habilitar el registro de errores para la depuración
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Cargar archivo init
require_once '/init.php'; // Actualiza esta ruta según la configuración de tu plataforma
// Clave secreta de Discourse Connect y URL para devolver el payload
$sso_secret = 'keyhere'; // Reemplaza con tu clave secreta compartida de Discourse
$discourse_url = 'https://urlhere.com/session/sso_login'; // Reemplaza con tu URL de Discourse
// Iniciar sesión para verificar el estado de inicio de sesión del usuario de la plataforma
session_start();
// Verificar si el usuario ha iniciado sesión
if (!isset($_SESSION['uid'])) {
// Si el usuario no ha iniciado sesión, redirigir a la página de inicio de sesión de la plataforma
header('Location: /clientarea.php');
exit;
}
// Depuración: Registrar los parámetros de la solicitud entrante
error_log("Parámetros GET recibidos: " . print_r($_GET, true));
// Verificar si recibimos los parámetros 'sso' y 'sig' de Discourse
if (!isset($_GET['sso']) || !isset($_GET['sig'])) {
error_log("Faltan los parámetros SSO o SIG.");
header('Location: /clientarea.php');
exit;
}
// Validar la firma SSO usando la clave secreta
$sso = $_GET['sso'];
$sig = $_GET['sig'];
$expected_sig = hash_hmac('sha256', $sso, $sso_secret);
if ($sig !== $expected_sig) {
error_log("Firma SSO inválida. Esperada: $expected_sig, Recibida: $sig");
header('Location: /clientarea.php');
exit;
}
// Obtener detalles del cliente de la plataforma
$clientDetails = localAPI('getclientsdetails', ['clientid' => $_SESSION['uid']], 'admin');
if ($clientDetails['result'] !== 'success' || !isset($clientDetails['userid'])) {
error_log("Error al obtener los detalles del cliente de la plataforma.");
header('Location: /clientarea.php');
exit;
}
// Extraer detalles del usuario
$userId = $clientDetails['userid'];
$email = $clientDetails['email'];
$firstName = $clientDetails['firstname'];
$lastName = $clientDetails['lastname'];
$username = $firstName . ' ' . $lastName;
// Decodificar el payload SSO
$sso_payload = base64_decode($sso);
parse_str($sso_payload, $sso_params);
if (!isset($sso_params['nonce'])) {
error_log("Falta el nonce en el payload SSO.");
header('Location: /clientarea.php');
exit;
}
// Preparar el payload SSO de retorno con los detalles del usuario
$return_payload = [
'nonce' => $sso_params['nonce'],
'email' => $email,
'external_id' => $userId,
'username' => $username,
'name' => $firstName . ' ' . $lastName,
'admin' => 0, // Establecer en 1 si el usuario es administrador, de lo contrario dejar en 0
'moderator' => 0 // Establecer en 1 si el usuario es moderador, de lo contrario dejar en 0
];
// Codificar el payload de retorno en Base64
$query_string = http_build_query($return_payload);
$encoded_payload = base64_encode($query_string);
// Firmar el payload codificado con la clave secreta de Discourse
$return_sig = hash_hmac('sha256', $encoded_payload, $sso_secret);
// Depuración: Registrar el payload y la firma
error_log("Payload de retorno: " . print_r($return_payload, true));
error_log("Payload codificado: $encoded_payload");
error_log("Firma de retorno: $return_sig");
// Redirigir a Discourse con el payload firmado
header("Location: $discourse_url?sso=" . urlencode($encoded_payload) . "&sig=" . urlencode($return_sig));
exit;
Registros de errores:
[25-Sep-2024 14:50:17 UTC] Faltan los parámetros SSO o SIG.
[25-Sep-2024 14:53:59 UTC] Parámetros GET recibidos: Array
(
[sso] => nonce_from_discourse
)
[25-Sep-2024 14:53:59 UTC] Faltan los parámetros SSO o SIG.
¿No estoy seguro de por qué?

