I followed a tutorial and no matter how many times I check this code, I can’t get it to work long term. Upon login the session starts,but after the set interval time when it should reset (60* 30
), the session gets destroyed and the user is logged out.
I’ve shortened the time to test this, setting the time to 60 * 3
and continuously refreshing the page every 30 seconds.
The session also died after 3 minutes, despite that page being the only one refreshed and the require being at the top of the page (require_once 'includes/config_session.inc.php';
)
How can I prevent the session from dying and keep the user logged in after using session_regenerate_id(true)
?
Here is the code for my 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();
}
2
Answers
This is due to the PHP’s session COOKIE not being refreshed upon each request or when we are calling the
session_start
function.The session COOKIE is being created once when we first call the
session_start
and then it is left as is.The logic behind this is that by default the
session.cookie_lifetime
param has a value of0
, meaning"until the browser is closed."
see: PHP docs > Session configuration.
You can also read the following bug report which describes exactly this "issue". One key point to keep from the comments there, is that if session cookie is not cleared upon browser closer (or session end), when a user, same or worse another one, reopens the browser on the same page, it will have kept the session!
Having said that, you can manually update the session COOKIE when needed. In your sample code that would be in the
regenerate_session_id_loggedin()
function since, you want to keep session for logged-in users.So you can add the following at the end of the function:
That should fix the timeout problem.
As a side note (irrelevant to the timeout), from the docs for the session_regenerate_id, you may also need to change your logic for creating a custom session ID. There is an example in the docs page above that suggest the following steps:
session_commit()
session_id('YOUR_CUSTOM_ID')
use_strict_mode
session_start()
, which will have the newly defined ID.use_strict_mode
like so:
Also note, that you call
session_regenerate_id
which renews the session ID and then you create and assign a new one.Furthermore, the
session_regenerate_id
is being called for all users regardless of their logged-in status, which is something you may or may not want.And a second note (this too is irrelevant to the timeout): You can make some refactoring to your code in order to not repeat some logic. e.g.:
Use session_write_close() Before session_regenerate_id(true):
After regenerating the session ID, it’s a good practice to call session_write_close() before continuing with the script. This ensures that the session data is written and closed before the new ID is generated. For example:
or
Check session.gc_maxlifetime Configuration:
Ensure that the PHP configuration setting session.gc_maxlifetime is set to a value equal to or greater than the session lifetime you’ve specified. This setting defines the number of seconds after which data will be seen as ‘garbage’ and potentially cleaned up.
at the end . please ensure that session_start() is called at the very beginning of each page before any output is sent to the browser. If there is any output or whitespace before the session starts, it can cause issues.