From what I thought I understood from sessions, this should be the case:
session times out based on what is set in the php.ini, lets say 30
minutes
if a user continues to browse and we update, lets say
$_SESSION['last_activity']=time();, then the session will be active for 30 minutes from the last activity
But what I am seeing is:
user logs in and session is started
user continues to browse
after 30 minutes, user is kicked off and annoyed, has to login again
Is this a server misconfiguration and why it is being destroyed even though the user is remaining active?
Thanks for the help!
Make sure you are calling:
session_start();
on every page that the visitor is accessing. This will reset the session clock.
Related
I am developing a simple php website named : http://www.dopanchat.com
In this site I used session to develop the login system, everything work fine but after some amount of time (for example, after 1 hour) the session expires automatically and user logged out from my site.
I don't know if it's server problem or anything else.
please help me to resolve this problem, you can check here : http://www.dopanchat.com
Extending your session timeout is an approach but I won't recommend to expand it too much :)
Instead your application could detect user activities and refresh the session expiry time accordingly.
After all it doesn't really matter what is the session's timeout at some point user will lose the authentication due to the expired session.
Basically the expiry count down always starts after user's last action and not from the moment s/he logged in to your system.
Try this :
// Time in secondes before the session expires
ini_set('session.gc_maxlifetime', 3600);
// Time in secondes before the ID's session in the cookie expires
session_set_cookie_params(3600);
// Start session
session_start();
If think this gonna work. Tell me if it work !
(Sorry for my bad english :D)
you can extend session expire time by adjusting php.ini file as follows
session.gc_maxlifetime=86400 //1 day
session.gc_divisor=5000
session.gc_probability=1
gc_divisor and gc_probability are responsible for cleaning expired session files, by above config session will valid for 1 day
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).
I've googled around about this and what I know so far is that the session is destroyed when the browser is closed and if the browser is just kept open, the session automatically expires after a fixed amount of time like 24 minutes.
But when does the counter for these 24 minutes start? When the server executes the session_start() line? This question might be a little long but please bear with me. Assume i have a php page with this code in it:
<?php
session_start();
?>
If a user open this page and just keeps it open for about an hour, will the session still expire although the page is still open? And if i add the session_start()code at the beginning of every page of my site, does the counter get reset to zero every time the user open a new page of the site?
Basically I want to make a login system that logs a user out when he closes the site or clicks the log out button and i want to keep him logged in as long as he has the site open, without him getting logged out automatically after 24 minutes or any other fixed time.
The timing starts when the session is first created. After the 24 minutes, it might or might not be erased by the garbage collector as it randomly kicks in(see session.gc_* directives).
What you want to do is regenerate the session every N minutes(session_regenerate_id()), so that it doesn't expire as long as the user is active.
I have a problem with logged in users closing their browsers.
My code can't run due to the browser closing and so their logonstatus cant update to 'N' in the database. Also due to the session being destroyed they cant go back to the main pages as I have this code if (!isset($_SESSION['logged in'])) { etc to prevent people from viewing any pages without logging in.
When a user logs on their logonstatus changes to 'Y' and I record the time they logged in.
I record their lastactivity time on each page load.
I redirect users to the login page and change their logonstatus if they have been idle for 20 min on a page.
I also have a cron job due to the browser close issue which runs every 5 minutes and checks if the users last activity has been longer than 20 min and if so their logonstatus becomes 'N'
I think users having to wait 20+ min to re-login due to browser close is too long and so I would like to make it possible to login in again straight away.
I have read about the unload functions of javascript but apparently it is unreliable.
Is there any other way I could go about this?
Closing the browser is always a client side action. So you will need javascript to send the action to the server for PHP to do something.
You can use onbeforeunload to send something to the server, but it is indeed unreliable. A more reliable method is to make the session time a lot shorter (eg: 2min) and then have an ajax call every 30seconds to the server to keep the session alive (make sure its a page with a very small impact on server/connection). If the request fails 4 times, the session is destroyed. Now your cronjob can run every 2mins and a user only has to wait that long.
Another approach is to store a cookie on the users computer with a GUID and save it in the database with the "Logged ='Y'". Now when somebody tries to log in to an account which is already logged in, check if its the same user (cookie) and if so, allow it.
This still makes it possible for one user to log in twice, just harder and not by mistake.
You need to change the duration of your session cookies so that they last as long as the browser window remains open; do this with session_set_cookie_params, setting the lifetime to 0. Don't forget to make sure that your cron script and PHP's session gc max lifetime don't delete sessions before 20 minutes have passed.
Since you keep a record of their last access time and check it on each request, you can continue to log out people after 20 minutes of inactivity (just destroy their session and redirect to the login page).
I'm running a php login script on my server. Whenever a user logs in the username is stored in $_SESSION['username'] and there exists a field in one of my DB tables called nonline used to store the number of users logged in.
When a user logs in, the value of nonline increases by one. And whenever a user logs out it decreases by one. Pretty neat so far. :P
The problem starts when, most of the users, like me, do not click logout, or visit the logout page as such. They log in, and just close their browser/tab when done. Doing so doesn't decrease the nonline value. So the value remains as such, even when the user is no more browsing my website.
Is there any way I can determine the number of users actually looking at my website at any given time so that its value changes even when a user closes his browser instead of clicking logout? I'm not using cookies for login.
Normally this will be done with a table which tracks last action, or last page load. The number n_online (you may want to add the _, noline starts with no, which is a little odd at first glance) will be the number who have made some form of action in the last n seconds - the number of people who actively logged out.
Unfortunately, there is not. Any solution that does what you want would involve the browser firing an HTTP request of some kind when the tab/window is closed, and this isn't going to happen.
The best you can do is have the users' sessions time out after a relatively short time (e.g. 15 minutes) and perform aggressive cleanup of expired sessions on every script that wants to know the actual number of active users. Be aware that this will be bad for performance.
If 15 minutes is still too long for you and you cannot decrease the session lifetime (because it would annoy your users if they were logged out after 10 seconds of inactivity), you can have your pages "ping" the server using AJAX to keep the session alive. This will allow you to have almost real-time results, but it will probably kill your performance, it will not work for users with JavaScript disabled, and is prone to malfunction if a user experiences transient connectivity problems.