【问题标题】:PHP $_SESSION maxlifetime not working properlyPHP $_SESSION maxlifetime 无法正常工作
【发布时间】:2020-09-16 08:51:55
【问题描述】:

对于我网站中的所有页面,我在顶部都有此会话检查:

<?php
// Initialize the session
if(!isset($_SESSION))
{ 
    session_start();
}
 
// Check if the user is logged in, if not then redirect him to login page
if(!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true){
  header("location: login.php");
  exit;
}
?>

我用它来检查用户是否登录。如果用户没有登录,他将被重定向到登录页面。

在 login.php 页面的最顶部,我有这个:

<?php

// server should keep session data for AT LEAST 8 hours
ini_set('session.gc_maxlifetime', 28800);

// each client should remember their session id for EXACTLY 8 hour
session_set_cookie_params(28800);

// Initialize the session
session_start();
 
// Check if the user is already logged in, if yes then redirect him to welcome page
if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){
    header("location: index.php");
    exit;
}

基本上这应该使会话持续 8 小时,是吗?

当用户成功登录后,我得到 SESSION:$_SESSION["loggedin"] = true;

我在这里做错了什么?当我将 SESSION 设置为持续 28800 秒 = 8 小时时,为什么我的用户在一段时间处于非活动状态后会不断退出/重定向到登录页面?

【问题讨论】:

标签: php


【解决方案1】:

当客户端请求中不存在会话 cookie 时,cookie 最初设置一次。这意味着:这些设置最初只应用一次,不是每次点击session_start()

当您启动会话时,cookie 时间开始到期,而不是您实际登录时。

因此,如果您提前访问该网站并开始 8 小时的会话,但您在 7.5 小时后登录,您的“登录”将在 30 分钟后过期(8 小时 - 7.5 小时 = 0.5 小时)。

从技术上讲,您的问题在这里:

<?php
// Initialize the session
if(!isset($_SESSION))
{ 
    session_start();
}

会话开始时没有特定的到期时间。 但是您想在会话开始时明确指定过期时间:

<?php
// Put this on top of ALL pages that RELY on session
if (session_status() === PHP_SESSION_NONE) {
    ini_set('session.gc_maxlifetime', 28800);
    session_set_cookie_params(28800);
    if (!session_start()) {
        throw new \Exception('Failed to start a new session');
    }
}

当有人成功登录时,你会喜欢:

<?php
if (login_successful()) {
    // Beware of race conditions in flakey wifi or with concurrent requests
    session_regenerate_id();
    $_SESSION['loggedin'] = true;
    $_SESSION['someToken'] = bin2hex(random_bytes(32));
}

稍后设置过期时间无效,因为如果没有更改值(或会话 ID),cookie 不会“刷新”。

您的代码还有两个问题:

  1. 没有session_regenerate_id(),您很容易受到会话固定https://owasp.org/www-community/attacks/Session_fixation的影响

  2. 您根本没有实施身份验证。每个人都可以通过使用 loggedin=true 创建一个本地 cookie 来“登录”您的站点。不检查密码或用户名。

【讨论】:

  • 他们已经在这样做了,session_set_cookie_params(28800);
  • 正如@CBroe 所说。我已经在第二行做到了:session_set_cookie_params(28800);.
  • 您所说的关于 TTL 的内容也不完全正确。当您登录时,新数据将被写入会话中,因此文件修改时间戳将被更新,这就是垃圾收集器决定清理哪些文件的基础。每次调用 session_start 都会更新 cookie 的生命周期。
  • @CBroe 我的第二段是关于客户端会话 cookie 的 TTL,而不是服务器上会话数据的时间戳。
  • 那又怎样,这仍然没有意义。 “你在 7.30 小时后登录” - 然后session_start 将在 那个 点再次被调用,因此一个具有 8 小时生命周期的新 cookie 将被设置为那个点。
猜你喜欢
  • 1970-01-01
  • 2015-11-15
  • 1970-01-01
  • 1970-01-01
  • 2019-01-13
  • 2021-08-16
  • 2012-10-28
  • 2013-10-13
  • 2012-12-06
相关资源
最近更新 更多