Understanding Session Time-out (php) - php

I need to delete old user datas in the DB, if user session is timeout.
How can I solve this problem with using PHP?

You can store the session_key with the rows in the database, and then define a time limit yourself. And then create a cronjob that delete's all rows with session_key's that has not been used within your limit.
A default session last until the browser is closed, so you cant know how many seconds that the session is active. Even when the session is closed, the session will not be deleted until the garbage collector removes it.

You can set the time for session time out . say 30 mins.
sesssion_gc_maxlifetime
You can check the login time of a user .
But if you want to delete the data , better to keep session in DB or at least
keep a status , login or logout and login time and logout time in the DB
It will be safe
So you can delete the data based on login time and current timedifference
set a cron job run in 30 mins or whatever time you wish

There is no way to add code to run when the session times out. You'll have to come up with a scheme yourself.
I'd suggest adding a timestamp to your database records and updating it every time the data is accessed. Then have a script via cron go through the records and delete those that are older than the session timeout.

Related

How to call a function before the idle timeout session expiry in PHP

I have a large application which expires the session data after 30 minutes of idle time. Now I want to call a function before the session expiration.
My Reason for above question: I am storing a unique id in database for some purpose. When the user clicks logout, I will delete that ID. I want to delete that ID even when the user session expires after idle time.
As far as i know , it will be bad practice to set a "counter" for users to check if their session is expired.
If you need this ID to see who is connected in your administration aria , one possible way to do it is by checking the session expiration on loading admin page , and then delete the expired sessions rows then showing only active sessions.
So my idea is that while you are not using your admin dashboard it is okay that some sessions ID's still in your database , once you try to see who is online , the check function is called and clean up your data for expired session.
THAT IF YOU ARE USING THAT ID FOR SOMTHING LIKE THAT SINCE YOU DIDN''T SHARE THE WHOLE REASON OF WHY YOU NEED TO DO SO.

PHP/MySQL Update database on session timeout

I'm working on a "flash website". In this program, I'd like to add an "Online Users" list, which relies on sessions: A session is started when a user logs in, and the user is marked as Online in the database. As soon as the logs out or closes the browser, the user is marked as Offline in the database.
I know that running some functions when the browser is closed will require Javascript, and it's not safe either: If the browser were to crash, the functions wouldn't run. That's why I've settled for the database updating if the user logs out or if the user's session times out.
I've been looking up session timeouts, and ran into this, along with many others like it marked as duplicates: How do I expire a PHP session after 30 minutes?
The problem with the answer's method is; It's a conditional sentence that checks if the user's last activity was X seconds ago, and if there was no activity, it times out. Useful in some websites, but useless for the Online Users list, since it updateds when a new request is sent, and since there won't be any requests after the user closes the browser.
Also mentioned in other answers is the use of session.gc_maxlifetime and session.cookie_lifetime, but the Best answer states that using them is a bad idea; One doesn't destroy the session, just the cookies, and the other is "cost-intensive".
What I want is the user to time out and the database to update and mark the user as Offline without using the If-Conditional sentence, or maybe with using a different If-conditional sentence that only has to be used once when the user logs in, like a timer or something, and whenever a request is sent, the timer restarts...those are just my ideas so far on how to solve this problem.
But, how do I do this? I'm sorry if the answer is something very simple and obvious, I'm very new to PHP.
Edit: Long Story Short:
I want to run a function after the user closes his browser, or is inactive for 20 minutes.
Clarification...
I want to update the database after 20 minutes of inactivity even if the browser has been closed.
I want to update the database after 20 minutes of the browser being
closed.
I don't think this is really possible to do with browsers being closed (reliably). If they click the logout button you can obviously run some code to mark the user as logged out. You can specify how long a session is good for with the functions you mentioned but all this does is makes the cookie be deleted on the client side, it doesn't trigger anything on the server side.
About the only thing you can do is track the time of the user's last activity and if they haven't had activity in a while assume they are gone. So just add a field to your user table and store a datetime or unix timestamp of their last activity. Then you can either run a cron job every few minutes that marks users as logged out or you can simply modify your SQL query to pull only users that have a last activity less than 20 minutes ago.
You can do this with the help of a online users table with last active field,
window.setInterval(function() {
$.ajax({
url: "http://yourdomain/updateLastactive/?uid=" + User_ID,
success: function(data) {
}
});
}, 5000); // 5 seconds
This page will update the current time-stamp as last active for that user
Then on online users query you can do like below,
SELECT UID FROM ONLINE_USERS WHERE LAST_ACTIVE > DATE_SUB(NOW(), INTERVAL 30 MINUTE));
if (!isset($_SESSION['CREATED'])) {
$_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
// session started more than 30 minutes ago
session_regenerate_id(true); // change session ID for the current session an invalidate old session ID
$_SESSION['CREATED'] = time(); // update creation time
}
Also read this
http://php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime
You want to catch the event by using the information here:
How to capture the browser window close event?
You will then need a page on the server that you call in that event handler with the sessionID.
That page calls a local script, page, or service that you set up to delay 20 minutes and expire the session. If you want to restart the clock if the user revisites before expiration, you will need to include a way to interrupt or cancel that script's process and you will need to retain the SessionID in a cookie which will need to be looked for upon every page load. If the cookie's SessionID is found and matches, the timeout gets interrupted/stopped (if it's still going). If it already completed, a new SessionID will need to be issued.
If you have a lot of these cancellations at the same time, you will instead queue them up on the server and have a process periodically check the queue and expire them as needed.
The way most sites avoid all this is to set a 30 minute or whatever session timeout that is enforced whether the visitor is active or not.
The easiest way to do this is to write a MySQL stored procedure that looks at the session timestamp and deletes the session data when it is > 20min old. You can also do it as an external cron job, but a stored procedure would be better.
In addition, you need to refresh the session timestamp every time the user connects.
If you want to make sure you don't delete a session when the user still has your 'page' open, then some background JavaScript refresh to your site will function as a keep-alive. Note that if the user closes the 'window' or 'tab', it will be the same as the whole browser being closed - I'm not sure you can do anything about this.
Of course, you to do this, you need to store your sessions in MySQL.
TL;DR
MySQL stored procedure or cron job deletes session if session_timestamp > 20min
Client-side Javascript does ajax refreshes to keep session open
Session timestamp updated every time the 'page' is requested (browser or ajax).

Session in PHP and Mysql

I want to create a page on which I can see, who is logged in on my site.
For every user after logging in I create a session, and send a query to change the row "Logged" in mysql from No to Yes.
Then, on the page I use PHP to show everyone, who has Yes set in mysql, and it works.
But, I have a problem, which occurs when someone close the browser without clicking Logout - the query doesn't execute and the Yes value in mysql stays...
What can I do to create a page like this?
Instead of having a boolean value for logged in or out, determine a reasonable amount of time for the session to expire (e.g., 1 month) and then add that amount of time to a timestamp and store that in the database as session_expires or something. Then you can check if the user's session has expired whenever you do your login checks.
Additionally, to manually expire the session (for instance if a user logs out) just set the session_expires field to a timestamp in the past.
EDIT
I didn't have access to a computer over the weekend, so I couldn't properly update my answer.
If you need to see active users, one thing I've done in the past is to use a last_seen timestamp field that updates any time the user does anything on the site. Then, on your "users logged in" page, just query for something recent like "last seen in the past 15 minutes."
You cannot do anything about that, but defining a timeout. That means your initial call after logging in that sets your customer row to "YES" should be triggered on every request (or to spare resources, every minute) to update a date column in that very customer row. If no update comes in anymore, you define that customer as "not logged in anymore" and update the column to "NO"
The fact that the user keeps on staying logged in is due to the PHP SESSION TIMEOUT which may be configured in PHP settings php.ini.
Have a look at http://php.net/manual/en/function.session-set-save-handler.php to learn how to set a session shutdown handler (that will be called once the session becomes invalid). When the shutdown handler is called, set your current session's "logged" to false in the database. Still, it may take up to 24 minutes (default value in php.ini for session timeout - session.gc_maxlifetime = 1440 minutes).
Decrease this value (session.gc_maxlifetime) to 2-3 minutes and have a ajax function on each of your pages keeping the session alive. This will definitely increase your server's load but you will definitely have a better representation of the currently active users. You can decrease the value from php.ini or by usig ini_set(‘session.gc_maxlifetime’,30); in your code.
Regards

Making a time based Trigger in PHP

For example, if I want to set up a trigger that fires every hr passed since the current time, how would I implement that?
I am using PHP to write my backend code, essentially, if a user logged in, I give a sessionID, if there's no activity every hr , then session timeout. I think it needs to be implement in PHP right?
You use the cron job scheduler to run your script.
For Windows, you can try the Windows Task Scheduler. It provides similar functionality.
Actually, you don't need cron to do this.
Since you want to end the session if the user has been inactive for one hour, how about you do this.
When the user visits any page, update a $_SESSION variable with the current time.
Once the user browses to a new page, check if the current_time - last_time > 1 hour. If so, end the session and redirect them.
You should do this with cron scripts, not in PHP. Having PHP scripts running for hours is generally bad practice.
No need for job scheduling here. When you give them a session ID, store the session ID in a table in your database. Then do this upon every single request:
if session id row is found
if current time - last updated time > 1 hour
Do not allow access. Session is expired
else
update timestamp of session id row, setting it to the current time
allow access
end
end
Essentially: every time the user requests something, you can update a timestamp field in that session's row in your database. If the current time - last updated time > 1 hour, then the session is invalid and you should not allow the access.
If you wanted to schedule a job to go delete or otherwise deactivate rows that have expired, that's fine, but your session management scheme should not depend on that.
That said, if you don't have to roll your own session management, don't. It's fraught with lots of little details that are easy to overlook, and could result in leaving your site vulnerable. If you still need to roll your own, check out some of the OWASP materials about session management and authentication:
https://www.owasp.org/index.php/Session_Management_Cheat_Sheet
either, set up a cron job that runs hourly, or instead set up code that retroactively calculates what needed to be calculated since the previous visit.
it would help emmensly if you were to describe what you are trying to accomplish in more detail.

Run query after session expire

I need a php code that will run a query after a specific session is going to expire,
if(!isset($_SESSION['test'])) query;
something like that but does work with session expire.
The problem you'll run into: a session doesn't just expire by itself, a session is expired on the next page load if the user waited too long. As there's no communication between browser and server between requests (user action), the server won't know if e.g. the user just closed the browser (or is doing the dishes while the website remains open).
So I guess there's nothing wrong with your code as it'll tell you if the sessin is expired on the next pageload (as long as there is a next pageload :)).
If you really need to make sure, the query runs after a session expired, I guess you'll have to save your sessions to a database and run a "cleanup"-script on each pageload to run your query and get rid of expired sessions. (e.g. save "lastUserAction" and compare that to whatever your session-limit is)
I would suggest to save the date you created the session in the database and check if the session expires like:
if($db->checkExpiredSession('test') == true) {
$db->query('...');
}
Just a thought.

Categories