PHP 和 403 问题 [已关闭]

问题描述 投票:0回答:1

所以我有一个带有 4 个简单按钮的 SPA。该网站实际上只是我的数字简历。我在顶部有两个按钮: 打开一个下载模式窗口,其中包含验证码。他们完成验证码,下载按钮被启用,它应该使用下载处理程序 php 脚本下载 pdf 文件,以保护文件免受机器人等的侵害。另一个按钮打开一个联系表单,其工作方式大致相同,这是一个允许发送的验证码按钮启用,以及实际发送的表单。该接触部分工作完美,发送消息等。

下载是我遇到问题的地方。它给了我一个 403 错误,从我的故障排除来看,验证码似乎没有被记录,但它必须被记录,否则按钮将无法启用并且不可点击。联系表单部分可以正常工作并发送消息,只是下载无法正常工作。

我尝试了我能想到的一切,甚至尝试使用 ChatGPT 进行一些故障排除,但目前我正在原地踏步。我不是开发人员,但知道的知识足以构成危险。有人可以提供一些指导吗?

以下是经过修订的两个主要文件:

form-handler.js:

document.addEventListener('DOMContentLoaded', function() {
    var contactModal = document.getElementById('contactModal');
    var downloadModal = document.getElementById('downloadModal');
    var notificationPopup = document.getElementById('notificationPopup');

    document.getElementById('contactBtn').addEventListener('click', function() {
        setupCaptcha('contactModal', 'contactCaptcha', 'RECAPTCHA_SITE_KEY', enableSubmitBtn, 'submitBtn');
    });

    document.getElementById('downloadBtn').addEventListener('click', function() {
        setupCaptcha('downloadModal', 'downloadCaptcha', 'RECAPTCHA_SITE_KEY', enableDownloadBtn, 'downloadLinkBtn');
    });

    document.getElementById('contactForm').addEventListener('submit', function(event) {
        event.preventDefault();
        submitForm(this);
    });

    document.getElementById('downloadLinkBtn').addEventListener('click', initiateDownload);
});

function setupCaptcha(modalId, widgetId, siteKey, callback, buttonId) {
    var modal = document.getElementById(modalId);
    var container = document.createElement('div');
    container.id = widgetId;
    container.className = 'g-recaptcha captcha-padding';
    container.style.textAlign = 'center';
    container.style.display = 'flex';
    container.style.justifyContent = 'center';
    container.style.padding = '10px 0';

    var button = modal.querySelector('#' + buttonId);
    button.parentNode.insertBefore(container, button);
    window[widgetId] = grecaptcha.render(container, {
        'sitekey': siteKey,
        'callback': callback
    });
}

function enableSubmitBtn() {
    document.getElementById("submitBtn").disabled = false;
}

function enableDownloadBtn() {
    document.getElementById("downloadLinkBtn").disabled = false;
}

function submitForm(form) {
    var recaptchaResponse = grecaptcha.getResponse(window.contactWidgetId);
    if (!recaptchaResponse) {
        alert("Please complete the CAPTCHA.");
        return;
    }
    var formData = new FormData(form);
    formData.append('g-recaptcha-response', recaptchaResponse);
    fetch('scripts/phpmailer.php', {
        method: 'POST',
        body: formData,
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            alert("Your message has been successfully received. Thank you!");
            form.reset();
        } else {
            alert("There was an error processing your request. Please try again.");
        }
    })
    .catch(error => {
        alert("There was an error processing your request. Please try again.");
    });
}

function initiateDownload() {
    var recaptchaResponse = grecaptcha.getResponse(window.downloadWidgetId);
    if (!recaptchaResponse) {
        showNotification("Please complete the CAPTCHA.", false);
        return;
    }
    fetch('scripts/download-handler.php', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({captcha: recaptchaResponse}),
        credentials: 'include'
    })
    .then(response => {
        if (response.ok) return response.blob();
        return response.text().then(text => { throw new Error(text || 'Download failed'); });
    })
    .then(blob => {
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = 'SampleFile.pdf'; // Adjust filename as needed
        document.body.appendChild(a);
        a.click();
        window.URL.revokeObjectURL(url);
    })
    .catch(error => {
        console.error("Error initiating download:", error);
        showNotification(error.message, false);
    });
}

下载处理程序.php:

<?php
session_start();

// Log session variables for debugging
error_log("Session CAPTCHA completed: " . var_export($_SESSION['captcha_completed'], true));

// Decode JSON input for PHP processing
$_POST = json_decode(file_get_contents("php://input"), true);

if (!isset($_SESSION['captcha_completed']) || $_SESSION['captcha_completed'] !== true) {
    http_response_code(403);
    echo "CAPTCHA verification failed or session expired.";
    exit;
}

$file = '/path/to/your/file.pdf';
if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/pdf');
    header('Content-Disposition: attachment; filename="' . basename($file) . '"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
} else {
    http_response_code(404);
    echo "Requested file not available.";
    exit;
}
?>

这是浏览器中的控制台输出(如果有帮助的话):

POST https://example.com/scripts/download-handler.php 403 (Forbidden)
initiateDownload @ form-handler.js?ver=1.5.4:80
form-handler.js?ver=1.5.4:100 Error initiating download: Error: CAPTCHA verification failed or session expired.
    at form-handler.js?ver=1.5.4:88:53
(anonymous) @ form-handler.js?ver=1.5.4:100
Promise.catch (async)
initiateDownload @ form-handler.js?ver=1.5.4:99
form-handler.js?ver=1.5.4:101 Uncaught (in promise) ReferenceError: showNotification is not defined
    at form-handler.js?ver=1.5.4:101:9

非常感谢任何帮助。我不是专家,您很快就会知道。

编辑:我已验证文件和文件夹具有正确的权限,并且位于具有正确路径的正确位置。从下载和测试中删除验证码确实允许下载文件。一旦验证码被放回,403。

编辑2:好的问题解决了,作为一个n00b,我忘记了会话标志。 添加了 set-session.php:

<?php
session_start();

header('Content-Type: application/json'); // Ensure the response is treated as JSON

// Security measure to ensure the request is a POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405); // Method Not Allowed
    echo json_encode(["error" => "Invalid request method."]);
    exit;
}

// Decode JSON input for PHP processing
$input = json_decode(file_get_contents("php://input"), true);

// Check if the CAPTCHA completed field is set and validate it
if (isset($input['captcha_completed']) && $input['captcha_completed'] === true) {
    $_SESSION['captcha_completed'] = true;
    echo json_encode(["success" => true, "message" => "Session updated successfully."]);
} else {
    $_SESSION['captcha_completed'] = false;
    http_response_code(400); // Bad request if the parameter is missing or incorrect
    echo json_encode(["error" => "Required parameters are missing or incorrect."]);
}
?>
php
1个回答
0
投票

感谢 showdev 和 Daedalus 在我第一次尝试时为我提供了一些急需的指导。对于反对票,谢谢,这些对新手没有帮助,也不太受欢迎。

答案是创建 set-session.php,showdev 让我寻找它。上面是该文件的内容,以防它对未来的新手有所帮助。

我错过了这个帖子的回答按钮,但代达罗斯让我到达那里。谢谢老弟!

© www.soinside.com 2019 - 2024. All rights reserved.