Проблема, с которой я сталкиваюсь, возникает, когда страница впервые загружается в новом сеансе. Код PHP выполняется до того, как код JavaScript сможет собрать данные на стороне клиента. В частности, вызывается функция отпечатка пальца, но, поскольку в этот момент в сеансе нет отпечатка пальца, запускается методgenerate_fingerprint(). Однако при сборе данных на стороне клиента данные POST недоступны (поскольку JavaScript еще не запущен), в результате чего функция возвращает значение null. Это приводит к сбою механизма блокировки в этом сценарии.
Это фрагмент кода, который у меня сейчас есть (в сочетании с файлом javascript) для генерации информации на основе клиентских данных для отпечатка пальца:
Код: Выделить всё
function generate_advanced_fingerprint() {
$components = [
'screen_resolution' => $_POST['screen_resolution'] ?? '',
'color_depth' => $_POST['color_depth'] ?? '',
'canvas_fingerprint' => $_POST['canvas_fingerprint'] ?? '',
'webgl_fingerprint' => $_POST['webgl_fingerprint'] ?? '',
'audio_fingerprint' => $_POST['audio_fingerprint'] ?? '',
'installed_fonts' => $_POST['installed_fonts'] ?? '',
'hardware_concurrency' => $_POST['hardware_concurrency'] ?? '',
'device_memory' => $_POST['device_memory'] ?? '',
'browser_features' => $_POST['browser_features'] ?? ''
];
if (in_array('', $components, true)) {
return null;
}
ksort($components);
$structured_data = json_encode($components);
$fingerprint = md5($structured_data);
return $fingerprint;
}
Это код, который я использую для генерации отпечатка пальца и выполнения проверка блокировки по черному списку (файл JSON):
Код: Выделить всё
function handle_fingerprint() {
if (!is_page('test')) {
return;
}
$is_post_request = ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SERVER['HTTP_X_FINGERPRINT_REQUEST']));
if ($is_post_request) {
// Process the POST data with client-side information
$raw_post_data = file_get_contents('php://input');
$json_data = json_decode($raw_post_data, true);
if ($json_data) {
$_POST = array_merge($_POST, $json_data);
}
}
// Generate or retrieve the fingerprint
if (!isset($_SESSION['fingerprint_generated']) || $is_post_request) {
$fingerprint = generate_fingerprint();
$_SESSION['fingerprint_generated'] = true;
$_SESSION['current_fingerprint'] = $fingerprint;
// Save the fingerprint if it is a POST request
if ($is_post_request) {
$ip = get_visitor_ip();
save_fingerprint($ip, $fingerprint);
// Send a response to the POST request
header('Content-Type: application/json');
echo json_encode(['success' => true]);
exit;
}
} else {
$fingerprint = $_SESSION['current_fingerprint'];
}
// Run the check
$blocked_fingerprints = get_blocked_fingerprints();
// Check fallback fingerprint
if (in_array($fingerprint['fallback_fingerprint'], $blocked_fingerprints)) {
wp_safe_redirect(home_url('/'));
exit;
}
// Check advanced fingerprint
if (isset($fingerprint['advanced_fingerprint']) && in_array($fingerprint['advanced_fingerprint'], $blocked_fingerprints)) {
wp_safe_redirect(home_url('/'));
exit;
}
}
// Check the fingerprint on every pageload
add_action('wp', 'handle_fingerprint');
// Process POST requests for fingerprint data
add_action('init', function() {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SERVER['HTTP_X_FINGERPRINT_REQUEST'])) {
handle_fingerprint();
}
});
Результатом является двойной вызов (который я могу увидеть в журналах ошибок).
Я пробовал создание отпечатка пальца только после того, как все данные доступны:
Код: Выделить всё
if ($all_data_present) {
if (!isset($_SESSION['fingerprint_generated'])) {
$fingerprint = generate_fingerprint();
$_SESSION['fingerprint_generated'] = true;
$_SESSION['current_fingerprint'] = $fingerprint;
} else {
$fingerprint = $_SESSION['current_fingerprint'];
}
Примечание:
Примечание: p>
- Я хочу, чтобы сообщения об ошибках не отображались. Я предпочитаю, чтобы они перенаправлялись на «фальшивую» страницу, призванную отвлекать, а не делать их мудрее, чем они есть.
- Я также хочу избегайте использования JavaScript для перенаправления. Я бы хотел остаться с wp_safe_redirect() или чем-то подобным, если это возможно.
Подробнее здесь: https://stackoverflow.com/questions/793 ... -collected