INSERT INTO tbl_session (user_id, token, expires)
VALUES :user_id, :token, DATEADD(Now(), INTERVAL 20 MINUTE)
ON DUPLICATE KEY UPDATE expires=DATEADD(Now(), INTERVAL 20 MINUTE)
This will either create or update a record in the session table keeping the table tight without garbage that needs to be collected.SELECT * FROM tbl_session WHERE token = :token AND expires > NOW()
If you want to update the session when the server is touched you can do thisUPDATE tbl_session SET expires = DATEADD(Now(), INTERVAL 20 MINUTE)
WHERE token = :token AND expires > Now()
You can do a check and set with the above query. After running the query check the rows affected (this will eliminate the need for the select)$sessionActive = $stmt->rowsCount() > 0;
That is what you use for normal page round trips.(function() {
const login = document.getElementById('login_button_id');
setInterval(checkSession, 60 * 1000);
/**
* Assumes a COOKIE based session token
* For a Header based token we would need
* to fetch the token from sessionStorage
* and add it to the header
*/
function checkSession() {
fetch('session_check.php')
.then(resp => resp.json())
.then(resp => {
if (!resp.status) {
// Assuming we do it your client's way
login.innerHTML = "Logout";
// usually we would do a redirect or a popup and then a redirect
}
}
}
})();
On the server we would then do the following.<?php
/**
* Common.php includes
* - config
* - database connection - for this example assumes PDO
* - creates session
*/
require_once('common.php');
/**
* Assumes the presence of a Session class - available on request
*/
$status = !!getSession($db);
sendJSON(['status' => $status]);
/**
* Simple function to send JSON response.
*/
function sendJSON($data) {
header('Content-type: application/json');
echo json_encode($data);
}
/**
* If using the PHP session
*/
function getSession() {
return $_SESSION[SESSION_TOKEN] ?? false;
}
/**
* If using DB method
*/
function getSession($db) {
$query = <<< QUERY
SELECT *
FROM
`tbl_session`
WHERE
`token` = :token AND
`expires` > NOW()
QUERY;
$session = false;
// SESSION_TOKEN Defined in config
$token = $_COOKIE[SESSION_TOKEN]
if ($token) {
$stmt = $db->prepare($query);
$result = $stmt->execute(['token' => $token];
if ($result) {
$session = $stmt->fetch(PDO::FETCH_OBJ);
}
return $session;
}
}
Then store the token as a cookie and every page view, grab the cookie, match the token up with your login table and check the end time. If it is past the time, you can log them out or send them a warning that they will be logged out and allow them to extend the time.
This will allow you to store an accurate time on their logged in pages when their session will end.
I use this type of thing myself on private projects.