views:

1638

answers:

9

I'm trying to log users out when the user's session timeout happens. Logging users out - in my case - requires modifying the user's "online" status in a database.
I was thinking that I might be able to use the observer pattern to make something that would monitor the state of the user session and trigger a callback when the session expires - which would preserve the user's name so we can update the db. I'm not exactly sure where to begin on the session side. Can I tie a callback to the session's timeout?

are these things built into any available pear or zend session packages? I will use whatever I have to to make this happen!

A: 

Why do you want to do this? The common approach is to check on every request sent by the user if the timeout has expired. Of course that means that the status in your db is not up to date, because the user is still shown as logged in, even though the timeout has been reached.

But for practical purposes that usually doesn't matter.

Treb
A: 

what if you have a system where users can interact with each other (but they can only interact with online users)? The user needs to know which other users are online currently.

If we simply check to see if the session is still alive on each page refresh, then after a timeout, the user is sent to a non-logged in page, but they are still listed as online in the system.

That method would be fine except that when we timeout the session, we lose the information about the user which could be used to log them out.

A: 

Ugly but maybe workable suggestion:

Add an asynchronous keep-alive requester to pages, that updates their last-active timestamp. You can then have a cron job that marks users as offline if they have a last-active timestamp more than 20 seconds old. Setting that cron job to run every minute would do the trick. I'm not sure there's a way to trigger something to happen when a user's session times-out, or closes their browser.

Dominic Rodger
+2  A: 

Take the simplest case first. Suppose you have 1 user on your system, and you want their session to timeout, and you want accurate reporting of their status. The user has not been to a page in 12 minutes, and your session timeout is set to 10 minutes. One of two things will happen. Either they will visit again in a short while, or they will not. If they don't visit again, how will the system ever run code to update their timeout status? The only way* is to have a separate process initiate a status update function for all users who are currently in status "in session".

Every time a user hits your site, update a variable in the database that relates their session to the last accessed time. Then create a cron job that runs every minute. It calls a simple function to check session statuses. Any sessions older than the timeout period are set to status "timed out". (You should also clean up the table after timed out sessions have sat for a while). If you ever want a report on the number of people logged in, query for all records that have a last accessed time later than the timeout interval start.

"*" There are other ways, but for the purposes of a simple web application, it's not really necessary. If you have something more complex than a simple web app, update your question to reflect the specific need.

Zak
Instead of the cron, do a simple user check atop the page's logic (look for cookie, check 'last_visited' column on user's db record, etc). So if the user decides to become active again, you can verify the user information and activity, and still be able to redirect as headers weren't sent yet.
invenetix
A: 

right. Thanks. I agree...sort of ugly. I already have some slow polling of the server happening, so it would be quite easy to implement that method. It just seems like such a useful feature for a session handling package. Zend and PEAR both have session packages.

A: 

"Then create a cron job that runs every minute. It calls a simple function to check session statuses. Any sessions older than the timeout period are set to status "timed out"."

this sounds great. Do you have any suggestions for checking session status? I have always been a little confused about how to check up on sessions. Are you suggesting that I store the session id in the database each time the user accesses the system?? If I do that, there's a table (somewhere on server?) that I can check the session ids against? did I get that right?

A: 

My first thought is that you could create a custom session handler that interprets being logged in as having an active session.

For some examples on creating a custom session handler see http://www.daniweb.com/code/snippet43.html and read the PHP doc http://ca.php.net/manual/en/function.session-set-save-handler.php

Allain Lalonde
A: 

Whenever a user hits a page, mark that time in the database, call this column LastAccessed. When the user clicks on the Logout portion of your site, you can set this value to null. When writing your query to find a list of users who are currently logged in, do the following:

SELECT *  FROM Users WHERE LoggedIn=1 AND LastAccess > DATEADD(Minute,-20.GETDATE())

Which would return the users who still have an active session. Pardon the SQL which probably doesn't work with MySQL/PHP, but this should give you a general idea.

Kibbee
A: 

I'm working on a user authentication system. My problem is with an "online status" element. So far, I have that when the user logs in, a field in my members MySQL table, called loggedinstatus is set to 1. This means that that certain user is currently logged in.

The problem is, is that the only way that loggedinstatus is set to 0 (the user is not logged in) is when the user clicks the logout link. If the user just goes to another website or closes his or her browser, the loggedinstatus is left at 1. How would I get around this problem?