↩️ Назад

Категории

add_comment.php добавление комментариев к статье или кодам блога

17.04.2026 | коды из категории: php

🔐 ЗАЩИТА:
- CSRF-токен с hash_equals()
- Проверка метода POST
- Валидация всех полей
- CAPTCHA (математическая)
- htmlspecialchars() + preg_replace() от XSS
- Белый список для post_type
- Ограничения длины (имя 2-50, текст 3-1000)
- Проверка ID поста > 0
- PDO подготовленные запросы

⚙️ ФУНКЦИИ:
- Приём AJAX-запросов
- JSON-ответы
- Сохранение в таблицу comments
- Запоминание имени автора в сессии
- Логирование ошибок в error_log

📤 ВОЗВРАЩАЕТ JSON:
- success: true/false
- message: текст ошибки или успеха
- comment: данные комментария (при успехе)

<?php
session_start();
header('Content-Type: application/json'); // Всегда возвращаем JSON

require __DIR__ . '/../includes/db.php';

// CSRF-токен: создаём, если нет
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// Проверка CSRF (защита от подделки запросов)
if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
    http_response_code(403);
    echo json_encode(['success' => false, 'message' => 'Ошибка безопасности: неверный токен']);
    exit;
}

// Проверка метода запроса
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'message' => 'Метод не разрешен']);
    exit;
}

// Валидация обязательных полей
$required = ['post_type', 'post_id', 'author', 'text', 'captcha'];
$missing = [];
foreach ($required as $field) {
    if (empty($_POST[$field])) {
        $missing[] = $field;
    }
}

if (!empty($missing)) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Обязательные поля: ' . implode(', ', $missing)]);
    exit;
}

// Обработка и очистка данных
$post_type = ($_POST['post_type'] === 'code' || $_POST['post_type'] === 'article') ? $_POST['post_type'] : 'article';
$post_id = (int)$_POST['post_id'];
$author = trim($_POST['author']);
$text = trim($_POST['text']);
$captcha = (int)$_POST['captcha'];

// Проверка: ID поста должен быть положительным
if ($post_id <= 0) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Неверный ID поста']);
    exit;
}

// Проверка длины имени
if (strlen($author) < 2 || strlen($author) > 50) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Имя должно быть от 2 до 50 символов']);
    exit;
}

// Проверка длины комментария
if (strlen($text) < 3 || strlen($text) > 1000) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Комментарий должен быть от 3 до 1000 символов']);
    exit;
}

// Проверка CAPTCHA
if (!isset($_SESSION['captcha_answer']) || $captcha !== (int)$_SESSION['captcha_answer']) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Неверная CAPTCHA']);
    exit;
}

// Фильтрация опасных символов (дополнительный слой защиты)
$author = preg_replace('/[<>]/', '', $author);
$text = preg_replace('/[<>]/', '', $text);

// Экранирование перед сохранением в БД
$author_safe = htmlspecialchars($author, ENT_QUOTES, 'UTF-8');
$text_safe = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');

// Сохранение комментария
try {
    $stmt = $pdo->prepare("INSERT INTO comments (post_type, post_id, author, text, created_at) VALUES (?, ?, ?, ?, NOW())");
    $stmt->execute([$post_type, $post_id, $author_safe, $text_safe]);

    // Сохраняем имя автора в сессию для удобства
    $_SESSION['comment_author'] = $author_safe;
    
    // Удаляем CAPTCHA из сессии
    unset($_SESSION['captcha_answer']);

    echo json_encode([
        'success' => true,
        'message' => 'Комментарий успешно добавлен',
        'comment' => [
            'author' => $author_safe,
            'text' => nl2br($text_safe),
            'date' => date('d.m.Y H:i')
        ]
    ]);
    exit;

} catch (PDOException $e) {
    error_log('DB Error in add_comment.php: ' . $e->getMessage());
    http_response_code(500);
    echo json_encode(['success' => false, 'message' => 'Ошибка базы данных. Попробуйте позже.']);
    exit;
}
?>



Категории:

Категории

Комментарии

Пока нет комментариев. Будьте первым!

Оставить комментарий

← Назад к списку

Посетителей сегодня: 0
о блоге | карта блога

© Digital Specialist | Не являемся сотрудниками Google, Яндекса и NASA