How to detect when a session ends - php

Is there a way to detect when someone leaves your site? So far I know about using ignore_user_abort() but thats about as far as I've gotten.
The reason I need to know this is because I need a script to execute upon someone leaving the site.

Record a timestamp in a database for each user and update this upon each page load (or through AJAX).
When the last updated timestamp is older than a cetain amount of time (30 mins?) you can consider they've left the site and do your code, deleting the entry afterwards.
Idea: a "user" could be a primary key made up of their IP and user agent as an MD5 hash for example.

1) I've found the Session Timeout Warning PHP Example with jQuery/JS article
2) Session timeout in PHP thread
3) Also article on how to do it with jQuery and ColdFusion

I can be done easily using javascript, check this solution
<body onbeforeunload="winCloseFunc();"> =)

Due to the stateless nature of http, there isn't an easy way to tell when someone leaves a site. It is possible to trigger onUnload when they leave a page, but this also fires as they navigate from page to page on your site.
Mozilla's Ref: https://developer.mozilla.org/en/DOM/window.onunload
MS's Ref: http://msdn.microsoft.com/en-us/library/ms536907(v=vs.85).aspx
Normally a session is setup to just expire when the user hasn't been seen in X minutes.

Related

How secure is it to use client side idle timer / how do big web app developers do it?

I'm building a PHP based web app and have implemented a session variable based login method. Before anything is loaded, this method clears the "logged in" state of all those that have spent X amount of time on the site without loading a new page or reloading the same page. Now this is working great, however this only does the check when the page is loaded and doesn't look for mouse / keyboard activity (think about a long form being filled out).
A similar question has been asked here however the code's security vulnerability was never questioned. I also found Paul Irish's solution to this however didn't find any reference to security there either.
Is it a realistic fear at all that the javascript code may be de-activated / intercepted in case I'd keep an "absolute timeout" server side? How do other big web app designers do it?
There's a number of inter-related issues here. My approach is that this can be done entirely server-side first, and then a JavaScript improvement added atop such that it doesn't matter if the client-side stuff fails to run.
The core of the solution is to set a last_seen time on the server when the user logs on. Whenever you detect any user activity (either a page rendering or an AJAX response), check whether this time is within acceptable bounds for you, and if it is overwrite it with the current time. If it is outside of the current bounds, destroy the session on the server side, and force a redirect to the login page, with a suitable message.
Once you have done that, there is no way that server-side value can be tinkered with, unless the user artificially refreshes their page pointlessly in order to avoid the timeout - but in that case, you would be unable to determine the difference between a "real" page request and one designed just to reset the session timer. If you are worried about malicious software on the user's computer, or an advanced man-in-the-middle attack on the user's connection, then you've got bigger problems than session timeout anyway.
Once this is set up, you may wish to use JavaScript to run a timer on each page that automatically shows the logged-off-automatically message. Just set this timer for the same length of time as your timeout, and of course restart it if an AJAX operation is triggered on the page. You could inject this message into the DOM, rather than redirecting, so if the user is filling out a form, they don't lose their work.
As you say, you could always detect form key-strokes to reset the timer. To do so, send an AJAX operation to the server that answers with an empty reply - that will send the cookie automatically - just ensure that your standard session code is run here too. Do use a JavaScript timer so that you don't send an AJAX op for every press - if it sometimes goes ten seconds later than the key press, then you'll not overwhelm the connection and you'll ensure your application remains speedy.

Inducing a function after session is destroyed

I'd like to induce a function after the session is destroyed (i.e. user closes the browser). This function would change a value in my database from true to false. Is that possible?
I would suggest you to register the user last activity in your database, this way it's 100% accurate.
Then by comparing the registered date with the current time, you can decide when the user is active or not.
If you really want to know if the user is still on your page, you could also do something, but you should avoid it :
On the client side, make a javascript loop, for example each minute, that tell to your server the client is still there. When the client will close his page, the loop won't make any new query.
I'm guessing that you're wanting to figure out whether a user is online or not (or something similar?) The only way to "know" (read: guess) that a session is dead is to store the time that the user was last active and then compare that time against the current time. Then, depending on your needs, you can decide to make the assumption that a user who has been inactive for 30 minutes is offline.
Only way to do this is using Javascript to detect a close and using a Ajax request (using XMLHttpRequest for example) to your PHP page (which handles the logout part).
See Browser/tab close detection using javascript (or any other language) for more information on the closing part.

PHP/JavaScript - detect which users currently have the page open

I want to make a page that will show all the users who are looking at that page right now. Ideally, a database would store which users are on the page and websockets would be used to update when users enter and leave.
The problem is that I don't know how to tell when users are viewing the page. I was thinking that I would be able to tell when they arrived and when they exited and add/remove accordingly. It's easy to tell when they arrive; however, it's difficult to tell when they leave - especially because users might do something like open multiple tabs, close one but keep the other open.
What is the best way to do this? I am using PHP as my server-side language.
You can use the blur and focus events on the window to toggle a variable. However, IE does some quirks which you will need to work around.
As a fallback to not working focus events, you might add a mousemove handler to the document. This might also throttle an automatic timeout which detects the loss of focus just by the fact that there was no user interaction for a specific period of time. However, you will never be able to detect a distracted user that has the site open but looks at something else...
To detect the window closing, you can hook on the unload event. This might be unreliable, but as you are using Websockets your server can easily detect a closed connection.
Well, one thing you could do, especially if you are using websockets is do a heartbeat/ping to the server every few seconds if you really wanted. If you don't get that heartbeat, you know they are not on the page anymore.... however, getting a response doesn't mean they are looking at the page, it would just mean that it is open, possibly in another tab. There is no way that I know of that will send a response to the server if the person loses focus on the page and opens another tab/window.
As Tim mentioned, Firefox and IE will run javascript in the background tabs, so there's no surefire way by simple polling to tell if the user is actually "looking" at the page or just has it open somewhere. Although I know of no way to tell if the user is actually looking at your page, a potential solution might be to bind polling to actions. So you might have some variable
var timesincelastaction=0;
var threshhold = 20;
Then
setInterval("timesincelastaction++",100);
Then
function keepAlive() {
if(timesincelastaction > threshhold) {
$.ajax(...tell the server you are alive...);
timesincelastaction = 0;
}
}
Then start thinking of actions like
$('a').mouseover(keepAlive);
$('div').mouseover(keepAlive);
$(window).scroll(keepAlive);
$(video).play(keepAlive); // okay this isn't a real one but you get the picture
So then you just brainstorm on everything the user can possibly be doing on the page that requires their attention and use those as your benchmark.
This seems a little intense I know, there's probably some nice ways to optimize it. Just thinking out loud. Curious to see what others come up with.
Every time one of your PHP scripts run, some user or entity has requested to view a page on your site (this usually occurs every time your script runs).
It is more challenging to detect when a user has left your page, which is why most online indicators are simply a timeout, i.e. if you have not been active on the website in the past 5 minutes, you are no longer considered online.
You can get information about the user who requested the page with variables like $_SERVER['REMOTE_ADDR'] or if you already have an authentication system you should be able to pull a users username, store this info in a database with the username/ip as a unique key with a timestamp, and simply not count them as online if their timestamp is older than 5 minutes.
You could probably use jQuery- ajax, unload and load. The ajax request will trigger on load telling you that they are viewing, and trigger on unload telling you they are no longer viewing. The rest is left to you to figure out because it sounds like you already have a grip on it.
Note. same result should be achievable in plain JS. Such as, onunload. Google will find you the rest.

How to store an accordion menu's state (open or closed) using Javascript or PHP

I would imagine it would be done with a cookie or session, but what is the best way to remember an accordion menu's state if a user opens an item and leaves? How can I have "open" items in that state when the user comes back to the site?
I've just upgraded my custom CMS with a new interface, and the new menu needs something like this or usability will suffer greatly.
I don't need specifics, just how you would normally do it.
Thanks!
http://www.shopdev.co.uk/blog/cookies-with-jquery-designing-collapsible-layouts/
this helped me out, hopefully it does for you as well.
I think you would need to save it to a database or use local storage (which isn't supported by all browsers). Cookies would work, but they can be deleted by the user (so can local storage). Sessions wouldn't work because once the user closes their browser, they lose their sessions.
Saving to a database or flat file is the most bulletproof way to do it.
Like most things, it depends.
If this is something that will make a server side request, then storing it in the session global would be completely acceptable.
If it's not, then you would need to find some other method of storing it client side. These would include things like storing it in javascript (only available the page's life), a cookie (like you mentioned) or like Bryan Downing mentioned with local storage. Local storage doesn't have good browser support yet.
Do you want it to be remembered regardless of the computer they log in from? If you do then set a simple value in a table associated to that user as to which item is open so it can be open the next time they return.
I use the jquery UI accordion and it's easy to update a field to which option was last selected so the next time the user comes back I can have that remembered for them. I've done this with a simple ajax call to request the value from the DB and return it to my javascript as a variable that's then used to set the opened accordion section.
If you're not worried about remembering across different devices then a simple cookie should do the trick, just updated the cookie each time a selection is made.

CodeIgniter is generating multiple sessions in the database. Why?

I have a site which does a few ajax calls on page load. For some reason, CodeIgnitor is inserting 4 sessions (I'm assuming one for each ajax call) as you load the page. I'm storing the sessions in the database.
I'm pretty sure there should only be one session per browser. Firefox seems to generate only one; other browsers seem to create a whole bunch of sessions. Multiple sessions for the same user are giving me some serious authentication problems.
Why is this happening? How can I stop it?
I know the discussion took place while ago, but somebody might find this useful.
By now I've used CI session without storing its data in database. Today I decided to give it a try and immediately run across the same problem: CI was generating new session in every page load.
I checked my server time, timezone, my cookie etc. - everything I could find as a tip on forums - with no result. Then decided to debug the CI Session class myself.
Long story short, it turned out that my user_agent field in my session table was too small - VARCHAR 50 - which cuts the original user_agent string - hence CI doesn't find my session and generates onother one. I just increased the user_agent field size to 200 and everything works like a charm.
I forgot to mention that I use Mac OS X Lion.
Again, hope this will help somebody.
Check the date / time on your client OS, and on your server.
I know its too late, but maybe someone finds this page while looking for the answer...
I think it happens because CI sets an expiration time on the cookie containing the session id and if the time difference between the server and client is higher than the expiration time the cookie gets old and the server will generate a new session for the client on every request. Never took the time to figure out the exact mechanism, but happened to me several times, and this fix always worked.
I've found this topic with same problem: on every page CI generates new session. Possible solution: remove underscored from site name ( NOT "my_test_site.com", but "my-test-site.com"). At least, this helped in my situation.
Check your config.php file and make sure the cookie options are properly filled out. If they are not it cant track the user and it will gen a new session on every page load.
Check the date / time on your client OS, and on your server.
I had the same situation and confirm the solution as a fix
$config['cookie_domain'] = "example.com";
Use your domain name in this snippet.

Categories