php - PHP $_SESSION maxlifetime 无法正常工作
问题描述
对于我网站上的所有页面,我在顶部都有这个会话检查:
<?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 小时时,为什么我的用户在一段时间处于非活动状态后会不断注销/重定向到登录页面?
解决方案
当客户端请求中不存在会话 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 不会“刷新”。
您的代码还有两个问题:
没有
session_regenerate_id()
,你很容易受到会话固定https://owasp.org/www-community/attacks/Session_fixation您根本没有实施身份验证。每个人都可以通过简单地创建一个本地 cookie 来“登录”到您的站点
loggedin=true
。不检查密码或用户名。
推荐阅读
- java - 在 Spring 中安排批量邮件作业
- rust - 无法运行 bellperson crate -“无法为 `fff v0.2.2` 运行自定义构建命令”
- php - 在 apache ldap.conf 中设置连接属性后,如何在 PHP 中实现使用 LDAP 池连接?
- sql - 如何在 SQL 中全选并添加一列?
- postgresql - 根据 PostgreSQL 11.0 中的常用列值将列转换为行
- javascript - 如何将自定义外部 css 链接(如 bootstrap css)包含到单个 REACT 组件中
- javascript - Angular Routes:多个插座,路径为字符串数组
- python - 如何在 pca 之后显示图像?
- arrays - 如何确保属性是打字稿中另一个属性的子数组?
- python - 调用 python 脚本运行 docker-compose ubuntu 时权限被拒绝