jsetzer wrote: ↑2023-02-21 05:44
This is possible to do but not trivial and requires a lot of Javascript code using AJAX and PHP code to write.
you're perfectly accurate in your analysis but I will say tools like chat GPT nowadays give us a great jump start for this kind of thing, just fed this prompt and got the following:
As you mentioned, a more robust solution could involve generating a unique client-side fingerprint that is stored on the server-side along with the user's session. This fingerprint can be generated by combining various browser and device characteristics such as browser type, screen size, installed fonts, etc. There are libraries and tools available that can help generate such a fingerprint, such as fingerprintjs2.
In addition to the fingerprint, a "keep alive" mechanism could be implemented, where the client periodically sends a request to the server to confirm the session is still active. If the server does not receive a keep alive request within a certain time frame, it can assume that the session has ended and log out the user.
Here are some steps you can follow to implement this approach:
Use a library such as fingerprintjs2 to generate a unique client-side fingerprint that is sent to the server during login:
javascript
Code: Select all
new Fingerprint2().get(function(result) {
// result is a unique identifier for the client's browser and device
// send result to the server during login
});
Store the fingerprint along with the user's session ID in the database:
php
Code: Select all
// Store the fingerprint along with the session ID in the database
$sql = "INSERT INTO user_sessions (user_id, session_id, fingerprint, last_activity) VALUES (?, ?, ?, NOW())";
$stmt = $pdo->prepare($sql);
$stmt->execute([$user_id, $session_id, $fingerprint]);
Implement a "keep alive" mechanism on the client side, using AJAX to send periodic requests to the server:
javascript
Code: Select all
setInterval(function() {
// send an AJAX request to the server to confirm the session is still active
}, 60000); // send request every minute
On the server side, check the fingerprint and last activity time for each session during login:
php
Code: Select all
// Retrieve the user's session and fingerprint from the database
$sql = "SELECT * FROM user_sessions WHERE session_id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$session_id]);
$session = $stmt->fetch();
// Check if the fingerprint matches the one stored in the database
if ($session['fingerprint'] !== $fingerprint) {
// Log out the user and display an error message
}
Log out the user and delete the session record from the database when the user logs out or the session expires:
php
Code: Select all
// Delete the session record from the database
$sql = "DELETE FROM user_sessions WHERE session_id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$session_id]);
// Destroy the session
session_destroy();
Note that while this approach can improve session tracking, it is not foolproof and can still be circumvented by determined attackers. Therefore, it is important to consider additional security measures, such as using HTTPS, implementing CSRF protection, and validating user input.