= 70300) { session_set_cookie_params([ 'lifetime' => 0, 'path' => '/', 'domain' => $domain, 'secure' => function_exists('cloak_request_is_https') && cloak_request_is_https(), 'httponly' => true, 'samesite' => 'Lax', ]); } elseif ($domain !== '') { session_set_cookie_params( 0, '/', $domain, function_exists('cloak_request_is_https') && cloak_request_is_https(), true ); } session_start(); } } class CloakFcheckCors { /** * OPTIONS 预检:在 session/bootstrap 之前调用。 */ public static function handlePreflight() { if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'OPTIONS') { return; } self::emitHeaders(); http_response_code(204); exit; } /** * 响应头(含 AJAX 跨子域 withCredentials) */ public static function emitHeaders() { $origin = (string) ($_SERVER['HTTP_ORIGIN'] ?? ''); if ($origin !== '' && self::isAllowedOrigin($origin)) { header('Access-Control-Allow-Origin: ' . $origin); header('Access-Control-Allow-Credentials: true'); header('Vary: Origin'); } header('Access-Control-Allow-Methods: POST, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type'); header('Access-Control-Max-Age: 86400'); } /** * @param string $origin */ private static function isAllowedOrigin($origin) { $originHost = parse_url($origin, PHP_URL_HOST); if (!is_string($originHost) || $originHost === '') { return false; } $requestHost = (string) ($_SERVER['HTTP_HOST'] ?? ''); if ($requestHost !== '' && strcasecmp($originHost, $requestHost) === 0) { return true; } $suffix = self::registrableSuffix($requestHost); if ($suffix === '') { return false; } $originSuffix = self::registrableSuffix($originHost); if ($originSuffix === '' || strcasecmp($originSuffix, $suffix) !== 0) { return false; } return self::hostMatchesSuffix($originHost, $suffix); } /** * @param string $host */ private static function registrableSuffix($host) { $host = strtolower(trim($host)); if ($host === '') { return ''; } if (function_exists('cloak_fingerprint_cookie_domain')) { $cookieDomain = ltrim(cloak_fingerprint_cookie_domain(), '.'); if ($cookieDomain !== '' && self::hostMatchesSuffix($host, $cookieDomain)) { return $cookieDomain; } } $parts = explode('.', $host); if (count($parts) < 2) { return $host; } return $parts[count($parts) - 2] . '.' . $parts[count($parts) - 1]; } /** * @param string $host * @param string $suffix */ private static function hostMatchesSuffix($host, $suffix) { $host = strtolower($host); $suffix = strtolower($suffix); return $host === $suffix || substr($host, -strlen('.' . $suffix)) === '.' . $suffix; } }