【问题标题】:User is being sporadically logged out (only happens in Chrome)用户偶尔被注销(仅在 Chrome 中发生)
【发布时间】:2020-05-26 01:29:56
【问题描述】:

使用我以前用来启动和存储会话的脚本,除了用户输入密码,我使用他们的 Windows 登录用户名并检查它们是否已经存在于用户表中。

在 index.php 页面上,这是我捕获 Windows 登录的方式:

<form>
  <h3><?php echo $_SERVER['REMOTE_USER']; ?></h3>
  <input type="hidden" id="winUser" value="<?php echo $_SERVER['REMOTE_USER']; ?>" />
  <button type="button" id="loginSubmit">Sign in</button>
</form>

这里是获取winUser ID的jQuery:

$('#loginSubmit').on('click', function()
{
  var winUser = $('#winUser').val();
  $.post('windowsUserCheck.php', {winUser:winUser}, function(data)
  {
    if(data.indexOf("Error") >= 0)
    {
      $('#errorModal').modal('show');
      return false;
    }
    else
    {
      location.href = "home.php";
    }
  });
});

这里是名为 windowsUserCheck.php 的进程:

<?php
include("include/sessions.php");

if(isset($_POST['winUser']))
{
  $windowsusername = $_POST['winUser'];

  $sql = 'SELECT `uid`, `username`, `fullname`, `department`, `email`, `password`, `userlevel` FROM users WHERE `username` = :username';

  $sth = $dbc->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
  $sth->execute(array(':username' => $windowsusername));

  $res = $sth->fetchAll(PDO::FETCH_ASSOC);
  $numrows = count($res);

  if($res[0])
  {
    $_SESSION['user']['uid'] = $res[0]['uid'];
    $_SESSION['user']['username'] = $res[0]['username'];
    $_SESSION['user']['department'] = $res[0]['department'];
    $_SESSION['user']['fullname'] = $res[0]['fullname'];
    $_SESSION['user']['email'] = $res[0]['email'];
    $_SESSION['user']['userlevel'] = $res[0]['userlevel'];

    echo "Success";
  }
  else
  {
    echo "Error";
  }
}
?>

这里是 session.php:

<?php
  if(!isset($_SESSION['user']['username'])){session_start();}  

  include("connection.php");

  $id = $_SESSION['user']['uid'];
  $username = $_SESSION['user']['username'];
  $department = $_SESSION['user']['department'];
  $fullname = $_SESSION['user']['fullname'];
  $useremail = $_SESSION['user']['email'];
  $userlevel = $_SESSION['user']['userlevel'];
?>

在站点中每个页面的顶部,我包含了一些脚本,这些脚本首先检查用户是否尝试在未登录的情况下导航到该页面。一旦他们登录,我会检查用户名是否为空或设置为 'guest',如果是,则将其注销:

<?php
  include("include/sessions.php");
  if(!isset($_SESSION['user']['username']) || $username == ""){header("location:index.php");}   
?>

使用以上所有,用户就可以登录了。问题是,当页面刷新时,用户被发送回index.php。这让我相信会话正在被清除或销毁,但我不确定如何。

为什么会发生这种情况?

编辑

我发现这个问题只发生在 Chrome 中。使用 Firefox 或 Edge 时,我可以整天保持登录状态。

【问题讨论】:

  • 来吧,现在。为什么投反对票?我的问题不清楚吗?
  • if(!isset($_SESSION['user']['username'])){session_start();} ,你认为会发生什么?我会告诉你:会议不会开始。我很确定。这也是马克也指出的。启用我在他的回答下的评论中看到的 500 错误的错误报告;这是服务器错误。
  • 我想知道你为什么在会话中使用多维数组?
  • 我不确定我为什么要使用这个数组。可能是因为我切换到 PDO,但我想我明白你在说什么。
  • 好的。好吧,我希望你能找到你的解决方案,约翰。

标签: php jquery session


【解决方案1】:

问题出在这里:

if(!isset($_SESSION['user']['username'])){session_start();}  

在声明 session_start() 之前,您正试图读取会话。

阅读自PHP.net documentation

session_start() 根据通过 GET 或 POST 请求或通过 cookie 传递的会话标识符创建会话或恢复当前会话。

在对会话进行任何操作之前,您需要声明 session_start(),无论是读取还是操作,因此只需将此行更改为以下内容即可:

session_start();

【讨论】:

  • 应该是无关的,我觉得调用session_start不会导致500内部服务器错误
  • 好吧,我在索引页的顶部扔了一个 session_start()。到目前为止,我还没有看到任何随机注销。但我担心日志文件会显示指向两个 session_start 调用的错误。如果一切正常,我会将您的答案标记为解决方案。
  • 我认为最好确保 session_start() 始终是第一个被调用的东西,并确保它只从一个位置被调用,就像你在 session.php 中所做的那样,对 session_start 的任何其他调用都应删除并替换为包含 sessions.php
  • 不走运。在索引页面上添加 session_start() 后,大约 6 分钟后它仍然让我退出。我只是不明白。我还在测试.​​..
  • 有趣,我想说试着弄清楚注销发生的时间点,我现在在手机上,所以我只能深入了解我可以查看的内容,但如果你可以编辑您的问题,更详细地了解您的发现。当我回到电脑前,我可以尝试帮助解决仍然存在的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
相关资源
最近更新 更多