'set', 'nonce' => $nonce, ]; } /** * verify 액션 — 세션의 nonce 를 반환하고 세션에서 제거 * * 세션에 nonce 가 보존되어 있으면 matched=true. 세션이 빈 상태(쿠키 round-trip * 실패) 면 matched=false. 한 번 verify 한 nonce 는 재사용 방지를 위해 세션에서 * 제거한다. * * @return array{action: string, matched: bool, nonce?: string} */ function sessionProbeVerify(): array { if (! isset($_SESSION['_installer_session_probe'])) { return [ 'action' => 'verify', 'matched' => false, ]; } $nonce = $_SESSION['_installer_session_probe']; unset($_SESSION['_installer_session_probe']); return [ 'action' => 'verify', 'matched' => true, 'nonce' => $nonce, ]; } // 라이브러리 모드: 테스트 등에서 함수 정의만 로드. SESSION_PROBE_LIBRARY 상수가 정의되어 있으면 즉시 종료. $sessionProbeLibraryMode = defined('SESSION_PROBE_LIBRARY') && constant('SESSION_PROBE_LIBRARY'); if (! $sessionProbeLibraryMode) { // 정식 진입점 — config / session / functions / guard 로드 require_once __DIR__.'/../includes/config.php'; require_once __DIR__.'/../includes/session.php'; require_once __DIR__.'/../includes/functions.php'; require_once __DIR__.'/_guard.php'; installer_guard_or_410(); header('Content-Type: application/json; charset=utf-8'); header('Cache-Control: no-store, no-cache, must-revalidate'); if ($_SERVER['REQUEST_METHOD'] !== 'GET') { http_response_code(405); echo installer_json_encode(['error' => 'GET method required'], JSON_UNESCAPED_UNICODE); exit; } $action = $_GET['action'] ?? ''; if ($action === 'set') { echo installer_json_encode(sessionProbeSet(), JSON_UNESCAPED_UNICODE); } elseif ($action === 'verify') { echo installer_json_encode(sessionProbeVerify(), JSON_UNESCAPED_UNICODE); } else { http_response_code(400); echo installer_json_encode(['error' => 'Invalid action — use ?action=set or ?action=verify'], JSON_UNESCAPED_UNICODE); } }