PHP 会话在页面之间丢失 - 行为因服务器而异

2024-03-31

我花了几个月的时间在我的域上开发一个应用程序。总的来说,这是一个简单的概念。在开发过程中,我自己将其托管在自己的域中,但最近将其推到了我们实际的域中。问题是会话不是在页面之间创建或保留的,我一生都无法弄清楚为什么。

对下面的代码墙表示歉意,但我更喜欢它而不是理论解释。

让我们从如何在每个页面顶部开始会话开始:

function sec_session_start() {
    $session_name = 'login';
    $secure = false;
    $httponly = true;

    ini_set('session.use_only_cookies', 1);
    session_set_cookie_params(86400, '/', '.domain.com', $secure, $httponly); 
    session_name($session_name);
    session_start();
    session_regenerate_id();
}

然后我如何检查用户是否已登录。我添加了return x;代替false用于调试。我将其附加到重定向 URL 中。

function login_check($mysqli) {
if(isset($_SESSION['id'], $_SESSION['login_string'], $_SESSION['type'])) {
    $id = $_SESSION['id'];
    $login_string = $_SESSION['login_string'];

    $user_browser = $_SERVER['HTTP_USER_AGENT'];

    if($_SESSION['type'] == 1 || $_SESSION['type'] == 2) // Admin user
    {

        if ($stmt = $mysqli->prepare("SELECT `password` FROM `users` WHERE `id` = ? LIMIT 1")) { 
            $stmt->bind_param('s', $id);
            $stmt->execute();
            $stmt->store_result();

            if($stmt->num_rows == 1) {
                $stmt->bind_result($password);
                $stmt->fetch();
                $login_check = hash('sha512', $password.$user_browser);
                if($login_check == $login_string) {
                    return true;
                } else {
                    return 1;
                }
            } else {
                return 2;
            }
        } else {
            return 3;
        }
    } else if($_SESSION['type'] == 3) { // Standard user
        if($stmt=$mysqli->prepare("SELECT `password` FROM `proj` WHERE `id` = ? LIMIT 1"))
        {
            $stmt->bind_param("s", $_SESSION['id']);
            $stmt->execute();
            $stmt->store_result();

            if($stmt->num_rows == 1)
            {
                $stmt->bind_result($db_key);
                $stmt->fetch();
                $login_check = hash('sha512', $db_key.$user_browser);
                if($login_check == $login_string) {
                    return true;
                } else {
                    return 4;   
                }
            }
        }
    } else {
        return 5;   
    }
} else {
     return 6;
}
}

我有两个登录页面,一个用于管理员,一个用于用户。

Admin:

<?php

ini_set('display_errors','On');
error_reporting(E_ALL);

include_once "../functions.php";
include_once "../db_connect.php"; 

sec_session_start();

if(login_check($mysqli) === true) {

header('Location: ../index.php');

}
else
{

// Login form

}

Users:

<?php

ini_set('display_errors','On');
error_reporting(E_ALL);

include_once "../functions.php";
include_once "../db_connect.php"; 

sec_session_start();

if(login_check($mysqli) === true) {

header('Location: ../index.php');

}
else
{

// Login form

}

除了管理员的文件源之外,完全相同login.php位于/admin。尽管如此,第一个正确显示登录表单,而第二个将您重定向到index.php(即使在隐身状态下,这对我来说也是一个谜),导致重定向循环(如index.php由于未登录而发回)。

除此之外,当我使用正确的凭据登录时,它确实会引导我index.php只是为了将我重定向回login.php有错误代码6.

如果您需要更多信息或代码示例,请发表评论,我现在对自己的项目感到迷失。

任何帮助表示赞赏, 谢谢

12 月 17 日更新:

经过几个小时的调试,我们得出的结论是问题不在于代码,而在于服务器配置。一个简单的例子:

<?php

session_start();
echo session_id();

?>

如果您在生产服务器上打开此文件并刷新页面,它将为每个请求显示一个新的会话 ID。我目前不知道为什么。我已确认会话文件和 cookie 均已创建。它包含正确的信息,并且可以通过具有服务器权限的 SSH 进行访问。确实有些奇怪的行为。

有什么线索吗?


我浏览了你的代码,没有发现任何异常,只接受一件事。

你永远不应该使用==用于字符串比较=== is OK.

$something = 0;
echo ('password123' == $something) ? 'true' : 'false';

运行上面的代码,你会发现会话丢失的原因。在您正在使用的函数 login_check 中==用于比较两个字符串

 if($login_check == $login_string)

将其替换为:

 if($login_check === $login_string)

其他一切都绝对没问题。如果改变这个小东西不能解决您的问题,请告诉我。

Advice

您正在会话开始之前连接到数据库。我建议您导入函数,然后启动会话,然后连接到数据库。

include_once "../functions.php";
sec_session_start();
include_once "../db_connect.php"; 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP 会话在页面之间丢失 - 行为因服务器而异 的相关文章

  • 使用 PHP 创建图表并导出为 PDF

    我正在寻找有关使用 PHP 创建图表的建议 我还希望能够将这些图表导出到 PDF 文档 我目前正在使用谷歌图表 但我不喜欢将我的所有信息发送到谷歌的想法 我更喜欢自己的托管解决方案 我见过很多 Flash 解决方案 但我不知道有什么方法可以
  • 准备好的语句需要 0 个参数,给定 1 个参数..,使用 php 手册示例 [重复]

    这个问题在这里已经有答案了 我直接从 php 手册示例中获取了这个 它几乎与我需要的相同 但我仍然收到此错误 有人可以告诉我我错过了什么吗 stmt link gt prepare SELECT obitBody Photo FROM tn
  • 如何检查号码是否是巴基斯坦用户的手机号码而不是固定电话号码

    我所做的是从开头删除 92 或 0092 并使用以下代码检查它是否是巴基斯坦人的有效手机号码 if preg match 3 0 4 0 9 number 1 Pakistani mobile number else not a pakis
  • MYSQL 的 Google OAuth 2.0 用户 ID 数据类型

    我正在实施 Google OAuth 2 0 并注意到 Google OAuth 返回的唯一用户 ID 是21位数字长的 我想大整数 20 足以满足这种需求 但我现在看到 Google OAuth 返回的用户 ID 的长度感到困惑 关于我应
  • PHP 文件上传帮助

    div align center div 这是我的代码
  • 压缩 zend Framework 2 的 html 输出

    我目前正在 PHP 5 4 4 上使用 Zend Framework 2 beta 开发个人 web 应用程序以用于自学目的 我想知道是否可以在 html 输出发送到浏览器之前拦截它 以便通过删除所有不必要的空格来缩小它 我怎样才能在ZF2
  • Laravel 5.1 中的VerifyCsrfToken.php 第 53 行:(Firefox 浏览器)中出现 TokenMismatchException?

    我试图找出为什么会出现这个错误 即使它是全新安装的 我在我的项目中遇到了这个错误 所以我用谷歌搜索 没有一个答案对我有用 所以我创建了新项目并复制了所有控制器 视图和模型 几个小时后工作正常 再次出现令牌不匹配错误 为什么在 laravel
  • php表格:每行显示3个单元格[重复]

    这个问题在这里已经有答案了 我看这里 数组放入每行 5 个单元格的表格中 https stackoverflow com questions 9099568 array into a table with 5 cells in each r
  • 关于加拿大短信网关提供商的建议[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我很好奇 如果我能够接受传入的短信到某个号码 然后将其传递给 PHP 中的服务器端应用程序 会带来多少麻烦 金钱 我最终会通过电子邮件地址发回短信 有
  • 具有动态表单名称的 form_widget

    在我的 Twig 模板中 我有一个 FOR 循环 它创建多个表单 如下所示 for thing in things set form id myform thing Id set form name attribute form myfor
  • 休眠会话已关闭

    当我调用方法 session begin 事务时 如下所示 session factory is instantiated via a bean Session session this getSessionFactory getCurre
  • strlen()==0 和empty()之间有区别吗?

    我正在查看其他人编写的一些表单验证代码 我看到了这个 strlen 0 当测试表单变量是否为空时 我使用empty 功能 一种方法比另一种方法更好吗 它们在功能上等效吗 strlen是获取字符串中的字符数 同时empty用于测试变量是否为空
  • Symfony2中如何获取所有post参数? [复制]

    这个问题在这里已经有答案了 我想获取a的所有post参数symfony http symfony com Form I used all parameter this gt get request gt getParameterHolder
  • Android GCM 服务器的 API 密钥

    我有点困惑我应该为 GCM 服务器使用哪个 API 密钥 在文档中它说使用 android api 密钥 这对我不起作用并且总是给出未经授权的 http developer android com google gcm gs html ht
  • 通过JS Laravel访问存储目录

    有没有办法访问storage目录 该目录已经链接到publicJS 中的目录 我正在尝试制作一个上传图片的表单 验证脚本 if request gt hasFile photos marker gt photos request gt ph
  • 如何在没有引用的情况下复制对象?

    PHP5 OOP 有据可查对象通过引用传递 http php net manual en language oop5 references php默认情况下 如果这是默认的 在我看来 有一种非默认的方式可以在没有参考的情况下进行复制 如何
  • PHP文件上传

    如果我想在文件名转到服务器的永久位置 而不是临时位置 之前更改文件名 我该如何执行此操作 代码如下
  • 上游太大 - nginx + codeigniter

    我从 Nginx 收到此错误 但似乎无法弄清楚 我正在使用 codeigniter 并使用数据库进行会话 所以我想知道标题怎么会太大 有没有办法检查标题是什么 或者看看我能做些什么来修复这个错误 如果您需要我提供任何conf文件或其他文件
  • 如何在 codeigniter 查询中使用 FIND_IN_SET?

    array array classesID gt 6 this gt db gt select gt from this gt table name gt where array gt order by this gt order by q
  • 检查文件权限

    我怎样才能检查file permissions 无需通过运行操作系统特定命令passthru or exec Use 文件权限 http php net fileperms功能 clearstatcache echo substr spri

随机推荐