Files
CLOAK/lib/Cloak/CloakSession.php
T
2026-06-15 22:42:59 +08:00

138 lines
3.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Session 与 f_check 跨域(CORS)辅助
*/
class CloakSession
{
public static function start()
{
if (session_status() === PHP_SESSION_ACTIVE) {
return;
}
$domain = function_exists('cloak_fingerprint_cookie_domain')
? cloak_fingerprint_cookie_domain()
: '';
if ($domain !== '' && PHP_VERSION_ID >= 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;
}
}