我遵循了教程,无论我检查此代码多少次,我都无法让它长期工作。登录后, session 将启动,但在设置的重置间隔时间(60* 30
)之后, session 将被销毁,用户将被注销。
我缩短了测试时间,将时间设置为 60 * 3
并每 30 秒不断刷新页面。
session 也在 3 分钟后终止,尽管该页面是唯一刷新的页面,并且需求位于页面顶部 (require_once 'includes/config_session.inc.php';
)
使用 session_regenerate_id(true)
后如何防止 session 终止并保持用户登录状态?
这是我的 config_session.inc.php 的代码
<?php
ini_set('session.use_only_cookies', 1);
ini_set('session.use_strict_mode', 1);
session_set_cookie_params([
'lifetime' => 1800,
'domain' => 'www.snoozelings.com',
'path' => '/',
'secure' => true,
'httponly' => true
]);
session_start();
if (isset($_SESSION["user_id"])) {
if (!isset($_SESSION['last_regeneration'])) {
regenerate_session_id_loggedin();
} else {
$interval = 60 * 30;
if (time() - $_SESSION['last_regeneration'] >= $interval) {
regenerate_session_id_loggedin();
}
}
} else {
if (!isset($_SESSION['last_regeneration'])) {
regenerate_session_id();
} else {
$interval = 60 * 30;
if (time() - $_SESSION['last_regeneration'] >= $interval) {
regenerate_session_id();
}
}
}
function regenerate_session_id() {
session_regenerate_id(true);
$_SESSION['last_regeneration'] = time();
}
function regenerate_session_id_loggedin() {
session_regenerate_id(true);
$userID = $_SESSION["user_id"];
$newSessionId = session_create_id();
$sessionId = $newSessionId . "_" . $userID;
session_id($sessionId);
$_SESSION['last_regeneration'] = time();
}
最佳答案
这是由于 PHP 的 session COOKIE 没有在每次请求时或我们调用 session_start
时刷新。功能。
当我们第一次调用 session_start
时, session COOKIE 就会被创建一次然后就保持原样。
这背后的逻辑是默认情况下session.cookie_lifetime
参数的值为 0
,意思是"until the browser is closed."
see: PHP docs > Session configuration .
您还可以阅读以下bug report它准确地描述了这个“问题”。注释中需要注意的一个关键点是,如果在浏览器关闭(或 session 结束)时未清除 session cookie,则当用户(相同或更差的另一个用户)在同一页面上重新打开浏览器时,它将保留 session !
话虽如此,您可以在需要时手动更新 session COOKIE。在您的示例代码中,该代码位于 regenerate_session_id_loggedin()
中函数,因为您希望为登录用户保留 session 。
因此您可以在函数末尾添加以下内容:
/**
* Renew the time left until this session times out.
* If we do not do this, the session will time out based on the
* time when it was created rather than when it was last used.
* @see https://www.php.net/manual/en/function.session-set-cookie-params.php#100657
*/
if(isset($_COOKIE[session_name()])) {
setcookie(
session_name(),
session_id(),
time() + (60 * 30),
'/',
'www.snoozelings.com',
true,
true
);
}
这应该可以解决超时问题。
作为旁注(与超时无关),来自 session_regenerate_id 的文档,您可能还需要更改创建自定义 session ID 的逻辑。上面的文档页面中有一个示例,建议执行以下步骤:
- 通过
session_commit()
保存并关闭当前 session - 通过
session_id('YOUR_CUSTOM_ID')
设置新的 session ID - 禁用
use_strict_mode
- 通过
session_start()
开始 session ,它将具有新定义的 ID。 - 启用
use_strict_mode
像这样:
// inside of your regenerate_session_id_loggedin
$newSessionId = session_create_id();
// Customize session ID for current USER.
$sessionId = $newSessionId . "_" . $userID;
// Write and close current session;
session_commit();
// Start session with new session ID
session_id($sessionId);
ini_set('session.use_strict_mode', 0);
session_start();
ini_set('session.use_strict_mode', 1);
// ... rest of your code.
另请注意,您调用 session_regenerate_id
这会更新 session ID,然后您创建并分配一个新 session ID。
此外,session_regenerate_id
正在为所有用户调用,无论他们的登录状态如何,这是您可能想要或可能不想要的。
还有第二个注释(这也与超时无关):您可以对代码进行一些重构,以免重复某些逻辑。例如:
<?php
ini_set('session.use_only_cookies', 1);
ini_set('session.use_strict_mode', 1);
// Init Session config vars.
$sessionCookieLifetime = 60 * 30;
$mySessionCookieParams = [
'lifetime' => $sessionCookieLifetime,
'domain' => 'www.snoozelings.com',
'path' => '/',
'secure' => true,
'httponly' => true
];
session_set_cookie_params($mySessionCookieParams);
session_start();
if ( ! isset($_SESSION['last_regeneration']) ) {
regenerateSessionByUserStatus();
} else {
if (time() - $_SESSION['last_regeneration'] >= $sessionCookieLifetime) {
regenerateSessionByUserStatus();
}
}
function regenerateSessionByUserStatus() {
session_regenerate_id(true);
if (isset($_SESSION["user_id"])) {
$userID = $_SESSION["user_id"];
$newSessionId = session_create_id();
$sessionId = $newSessionId . "_" . $userID;
session_id($sessionId);
/**
* Renew the time left until this session times out.
* If we do not do this, the session will time out based on the
* time when it was created rather than when it was last used.
* @see https://www.php.net/manual/en/function.session-set-cookie-params.php#100657
*/
if(isset($_COOKIE[session_name()])) {
setcookie(
session_name(),
session_id(),
time() + $sessionCookieLifetime,
$mySessionCookieParams['path'],
$mySessionCookieParams['domain'],
$mySessionCookieParams['secure'],
$mySessionCookieParams['httponly']
);
}
}
$_SESSION['last_regeneration'] = time();
}
关于php - 使用 session_regenerate_id(true) 后 session 终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77435811/