How to retrieve logout time - php

I have built a simple cakephp app with simple user authentication. It works. I have a problem when the user is idle for longtime, the app logs out the user. The user should log back to perform actions on the app.
My question is there is anyway I can save the time when the user was logged out.
I appreciate any help.
Thanks.

Ivanka,
what Thariama wrote seems to be quite sound. Nevertheless, if you need the feature to show the user status to others, imho you have to work with cron jobs and cake shells.
You would need:
Thariama's suggestion with the timestamps
The cake shell + cron job going over every logged in user. Once NOW - lastActionTimeStamp > maxIdleTime, log user out and persist timestamp.
Adding the second point has the benefit that other users do not see the logged out one as present/active, as it could be the case if you stick with 1. alone.
Depending on the size of your userbase, you can set the checking interval.
Another approach could be to implement some kind of client side timer (JS/AJAX) triggering a logout, which could be unreliable in nature, but should be even easier to implement.
My 2 cents.

On your server/application there will be a configuration setting which defines the idle time span after which a user gets logged out. With this knowlege (i am sure you know where to look) you are able to ddo the following
$time_span_to_logout_user = 600; // example 10 minutes
Everytime a user is logged in and requests one of your websites pages you simply store this timestamp into the db.
To get to know the loggout time you simply take this timestamp from the DB and add the $time_span_to_logout_user -> this is the user loggout time.

You can set it on app/config/core.php:
Configure::write('Session.timeout', '120');
Documentation explains this variable depends on security level.

Yes, write your own session handler and log the time using the gc and destroy fns

Related

Logout issues in a single-user system

I've been asked to build a project management application that could only host one user at a time. I managed to do that by simply creating a status row in my user table which is set to 1 when somebody is logged in.
Now, status = 1, nobody else can log in, they get an error message instead saying that another user is already using the application. When the online user logs out, I update the status row in the database and set it to 0 in order to allow other users to log in freely.
Everything is working just fine except, as you can see, it relies on the logout button and many users forget to logout that way, they just close the tab or the browser leaving status as 1 and then blocking the whole system.
I tried a few methods to update the database on page close with session timeout or via onunload but I couldn't reach a clean and reliable way of doing so.
How could I develop such a system combining single-user mode and auto/smart logout at the same time?
Thanks for your help.
The only way you can achieve this is by checking whether the logged in user has been active in the last X minutes. Check this when the new user tries to log in. When the previous user has been inactive for that period, unset the status in the database and let the new user in. You should then also invalidate the session of the previous user, in case he comes back.
Don't try to detect session endings.
You could reduce the user's Session timeout. I think you can accomplish that both from Php and the Webserver (Apache, IIS, ..), should really look at the man pages. That done, you could realize a polling system which periodically ping the user to verify his/her presence. For example, you could make a client-side Ajax script which pings the site at fixed intervals, so that would prolong the user's active Session. If the user doesn't ping the site anymore, after the time-window has expired, then set his/her status = 0.
That is just an idea. Try searching more about on Google.
A variant: you could set a cookie from the server-side language, and associate the session with that cookie. So, give it a short expire time. Then make a client script which periodically send a hidden request to the server. When the server receives the request, it re-write the cookie again, so the new time will start again from the beginning.

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.

Check if user is offline

I have an online game. I wish to show how many user are online. The problem is to know when a user is offline.
Is there a way to perform a check on sessions cookie to acknowledge whether the session with the broswer was closed?
I was thinking about simply set a timeout on the server which launch a script that count how many session cookie are present, but how do I check if the session cookie is about somebody who's logged and not just a visitor?
How did you handle this?
1) I don't want to rely on a script fired with the logout button, since nobody ever logout... people simply close the browser.
2) About timestamps and registering activity? Since in my game users interact with an svg (not moving through pages), they generate a huge amount of clicks. Making a query for each click for each of them refreshing a record would be very expensive.
When the user interacts with the site, set their last activity time.
If it is longer than 30 mins or so, you can assume they are offline.
You can also explicitly set someone to offline when they click logout.
However, your case is a little different. You could use a heartbeat style script.
Whilst they are on the page, use setInterval() to extend the expiry date, up to a maximum range (in case the user leaves their browser window open for hours on end).
Since your code gets executed when the page is loaded you cannot make a check if the user closed his browser or not.
So the common approach would be to use timestamps and update this stamp if the user does something on your site and if the timestamp is older than say 5 minutes you just assume he is offline

Detect online users?

I'm not sure what would be the easiest way to do this. I need to be able to detect what users are online on my website. So when people are viewing a thread or something it will say next to the users name if they are ONLINE or OFFLINE. And at bottom of forum index it will say all the users who are online.
What would be the easiest approach to do something like this? I'm not sure if I will need a Javascript which would run every time a page loads or what.
Thanks :)
have a MySQL database with a user table
have a column in that user table which saves the "last seen"-time
update that column on every page request
when checking for online or offline, check if current time minus "last seen"-time is greater than some treshold you like
Edit: You could optionally make a javascript "ping" the server (request an empty page) every two minutes or so if you want people idling with your Website open to be displayed as online, too.
One approach is to store your users sessions in a database or another store like memchached (or ideally both What is the best way to handle sessions for a PHP site on multiple hosts?). Then you just look up the user in your store and see if their session is still active.
A solution like this: http://pureform.wordpress.com/2009/04/08/memcache-mysql-php-session-handler/
You need to hold some kind of a "session" table, where you hold the user and the time of when they visited a page.
If the time is older then 5 minutes the user is offline (and the row can be deleted).
The other users in the session table are "online".
First thing first, there's no way to accurately get the current online users count. The best you can do is get a rough number.
Think about this situation: a user logs in to your website, clicks some links, and just closes the browser tab without logging out. Actually this is quite common. Your server never knows that a user closes the browser, so the session of that user keeps alive for some time (30 minutes maybe) if the session stored on your server.
In some stateless web apps like Ruby on Rails apps, sessions are stored completely on the browser side (in the cookies), and the server totally forgets about the user after each request, and that makes counting online users nearly impossible. This is a tradeoff for simplicity and scalability.
So how can we get such a number? We must make assumption basing on compromise. We make such an assumption that a user is online if his/her last request was made less than 30 minutes ago, then we can get the number of "online" users by tracking the timestamp of the last request each user makes. Or we can assume that a user is online if his/her session on the server is still alive, and count the sessions on the server. Either way, we have to convince ourselves that the number of "dangling sessions" is negligible (I know it's hard).

php observer pattern to log user out when session times out

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!
UPDATE # 16:33:
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.
UPDATE #16:56:
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.
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.
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.
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.
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.
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
I know this might be a older question but the "best" answer to your question is found here:
http://www.codeguru.com/forum/archive/index.php/t-372050.html
Here is what it says:
The php.ini file contains a setting called sesison.save_path, this determines where PHP puts files which contain the session data. Once a session has become stale, it will be deleted by PHP during the next garbage collection. Hence, a test for the presence of a fiel for that session should be adequate to determine whether the session is still valid.
$session_id = 'session_id';
$save_path = ini_get('session.save_path');
if (! $save_path) {
$save_path = '.'; // if this vlaue is blank, it defaults to the current directory
}
if (file_exists($save_path . '/sess_' $session_id)) {
unlink($session_id); // or whatever your file is called
}

Categories