首页 > 解决方案 > (已解决)一些本地工作的会话和功能突然在远程服务器上不再工作

问题描述

我三个月前才开始学习代码,所以所有的谜团都可能只是初学者的错误。让我们总结一下问题:

我制作了一个在 localhost(带有 PHP 7.3 的 wampserver)上仍然运行良好的 CMS,但突然停止在我的域(OVH 主机)上运行良好。神秘的是,在将 CMS 重新定位到子域(当时它仍然有效)之后,我重新生成了 LetsEncrypt SSL 证书(此时它停止工作),问题就出现了。

我联系了房东:显然 SSL 证书很好。停止工作的页面都使用会话变量:验证码、忘记、登录、注销、注册。

所以我在这里检查了许多会话变量问题线程,但它仍然对我的情况没有帮助。

例如:我试图 var_dump 子域上的一些会话变量:没什么奇怪的,它准确地显示了预期的内容。然后我想知道这是否是 CHMOD 问题,所以我检查了所有文件是否实际上是 CHMOD 644 :它们是。我试图恢复到 PHP 7.2:什么都没改变。我什至删除了一些 .htaccess 文件,以检查它们是否设置得如此糟糕导致了问题:什么都没改变(我把它们放回去了)。

我的托管计划不允许我访问 php.ini 来比较服务器版本和我的本地版本。所以我有点卡住了。

更新

我有一个新假设:服务器不像以前那样处理我的 POST 方法。在开发人员工具中,回显的 POST 方法文件只是“/”。

我在 ifItIsMethod 函数中添加了以下条件(该函数在本文末尾进行了描述):

if(empty($_SERVER['CONTENT_TYPE'])) {
$_SERVER['CONTENT_TYPE'] = "application/x-www-form-urlencoded";
}

现在 POST 方法文件返回“index”,这听起来像是一个进步。明天我将编辑我的 .htaccess 文件以设置 post_max_size,但新假设是 HTTP(或 IIS)与 POST 混淆。


第 7 天:

所以我 var_dumped 我的(非常基本的)login_user 函数的每个变量:

function login_user($username, $password)

{
    global $connection;
    $username = escape($username);
    $password = escape($password);

    $query = "SELECT * FROM users WHERE user_name = '{$username}' ";
    $select_user_query = mysqli_query($connection, $query);
    if (!$select_user_query) {
        die("QUERY FAILED");
    }

    while($row = mysqli_fetch_assoc($select_user_query)) {
        $db_id = $row['user_id'];
        $db_name = $row['user_name'];
        $db_password = $row['user_password'];
        $db_firstname = $row['user_firstname'];
        $db_lastname = $row['user_lastname'];
        $db_email = $row['user_email'];
        $db_role = $row['user_role'];
    }
    $password_verify = password_verify($password, $db_password);
    if($username === $db_name && $password_verify === true) {
        $_SESSION['user_id'] = $db_id;
        $_SESSION['user_name'] = $db_name;
        $_SESSION['user_firstname'] = $db_firstname;
        $_SESSION['user_lastname'] = $db_lastname;
        $_SESSION['user_email'] = $db_email;
        $_SESSION['user_role'] = $db_role;
        redirect("admin");
    } else {
        redirect("index");
    }
}

$row 包含所有预期的信息

$_SESSION 什么都没有...

...但这是因为 password_verify() 返回“false”

当时的新假设是:可能是服务器的更改弄乱了密码解密,让我们尝试更改它。

但是忘记的页面也坏了!并且此功能不使用密码验证。

它的PHP部分如下:

if(ifItIsMethod("post")) {
    if(isset($_POST['email'])) {
        $email = escape($_POST['email']);
        $length = 50;
        $token = bin2hex(openssl_random_pseudo_bytes($length));
        if(email_exists($email)) {
            $query = "UPDATE users SET token = ? WHERE user_email = ?";
            $stmt = mysqli_prepare($connection, $query);
            mysqli_stmt_bind_param($stmt, "ss", $token, $email);
            mysqli_stmt_execute($stmt);
            mysqli_stmt_close($stmt);
            $mail = new PHPMailer(true);
            $mail->isSMTP(true);
            $mail->Host       = SMTP_HOST;
            $mail->Username  = SMTP_USER;
            $mail->Password   = SMTP_PASSWORD;
            $mail->Port       = SMTP_PORT;
            $mail->SMTPAuth   = true;
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            $mail->isHTML(true);
            $mail->CharSet = "UTF-8";
            $mail->setFrom('postmaster@raphaelbadawi.fr', 'RB Blog Postmaster');
            $mail->addAddress($email);
            $mail->Subject = "RB Blog - Réinitialisation de votre mot de passe utilisateur";
            $mail->Body = "<h4>Bonjour,</h4><p>Cliquez sur le lien suivant pour réinitialiser votre mot de passe : <a href='https://blog.raphaelbadawi.fr/reset.php?email=" . $email . "&token=". $token ."'>lien</a>.</p><small>L'équipe RB Blog</small>";
            if($mail->send(true)) {
                $emailSent = true;
            }
        } else {
            $msg = "Cette adresse ne correspond à aucun utilisateur connu";
        }
   }
}

这是 ifItisMethod 函数:

function ifItIsMethod($method = null) {
    if(empty($_SERVER['CONTENT_TYPE'])) {
        $_SERVER['CONTENT_TYPE'] = "application/x-www-form-urlencoded";
    }
    if($_SERVER['REQUEST_METHOD'] == strtoupper($method)) {
        return true;
    } else {
        return false;
    }
}

我不知道下一步该做什么。


第 8 天:

检查 SQL 表以防万一:令牌是文本,密码是 varchar 255,看起来不错。


第 8.5 天:

问题解决了!该数据库包含在本地散列的密码。使用远程服务器重新散列它们基本上解决了登录问题。由于一个过时的 $_GET 检查我忘记在页面顶部静音(在此函数的第一个版本中,令牌是通过 URL 传递的),所以 forgot 函数有问题。

我想感谢大家一直以来都在关注这个问题。它确实有助于消除一些假设。没有你,我肯定还在。谢谢!

标签: php

解决方案


听起来像cookie问题。使用 PHP,您的会话 ID 保存在 cookie 中,但 cookie 可以受其域、到期时间(可能受服务器影响并最终成为过去时间)和路径的限制。请确保这些与新的服务器设置相匹配。这是迁移时 cookie/会话的常见问题


推荐阅读