Do you use cookies or session to time out or lock out someone from your website if they have used it for 2 hours? I want it to lock and have them wait an hour before them using it again.
I got the idea from this website that had a message pop up and say
"you have used this site for 2 hours, please wait an hour and come back or become a member and get unlimited hours"
Two approaches:
The simple one, in which you set a cookie or session (both use cookies in the end, so it hardly matters) to identify a user. The problem with this is that a user may simply discard his cookies or use a different browser, so this solution will only ever work for rather clueless users. It is probably good enough for your use case.
Go crazy with fuzzy identification of users via neural networks, which may/would allow you to identify users pretty uniquely in a way that would not allow them to "change their identity" easily. This is a really complex solution though and may be overkill or unrealistic for your purposes.
probably this will be helpful to you
if( !isset($_SESSION['last_access']) || (time() - $_SESSION['last_access']) > 60 )
$_SESSION['last_access'] = time();
This will update the session every 60s to ensure that the modification date is altered.
please visit below link to know more details with php code
http://riturajkumar12.blogspot.in/2014/04/expire-session-automatically-after.html
Related
I have developed this PHP web application which is now running for some months. Suddenly one of the users complained that he was able to login, but the session was terminated as soon as he clicked on any button! The same problem happened on different browsers.
After some tests I realized that a brand new session ID was created every time the user clicked on any button, probably because the original session was expired.
For whatever reason I took a glance at the user's computer clock and... surprise! His clock was 3 months in the future! I didn't know if such thing could have any relation to the failure, but I did fix the clock. Still it didn't work. I erased all cookies. Still nothing. So I restarted the browser - and then it started working again!
The closest information I got about this issue was Shimon Amit's answer to this question. Good, now I know that the clock "misconfiguration" is the cause. The problem is... I cannot keep every customer's computer clock under control. Some of them may have their computer clocks set in the future.
My question: is there any solution for this? Any trick? I don't want customers to face such errors as they may find it "lame" and break their trust on the application, even though it's not really my fault (in a sense).
Session cookies (like all cookies) are controlled and deleted when expired by the client browser. Even if you set a far out expire date (which you might not want to do anyhow) all the client needs to do is move his clock even farther forward and it will expire.
You can extend your session timeout to a later date. Perhaps you can use cookies that don't expire (sessions are related to cookies on the client side) Otherwise, your client's browser is just doing what it's designed to do.
EDIT: Javascript Option
This is a total hack, but you COULD use javascript to get the current time on the client machine and send it back to the server, then adjust the timeout on your session cookie to expire three months after that. See http://www.w3schools.com/jsref/jsref_gettime.asp
Once you have retrieved the client time, you can reset the session expiration using session_cache_expire(). http://www.php.net/manual/en/function.session-cache-expire.php
EDIT: 100% Server Side Option
Another option that I thought of would be to set a session cookie with no expiration, but track the time the cookie was set on the server, say in a MySQL table. You would also need to keep track of the last activity. Whenever a logged in user makes a request, you could check the start time of their session and their last activity. If the current time is greater than your acceptable timeout for either of these, then destroy the session server side and bring them back to the log in page. If the session is still ok, then update the last activity associated with that user so you can compare on the next request. No client side code necessary.
I fully agree with #MarcB's comment that you can't assume responsibility for how grossly misconfigured a user's machine could be. If you really want to make a difference in this regard I would suggest using PHP to output a small snippet of javascript that includes the time on the server. The snippet would compare that time to the time on the client computer and raise an alert if the time differs by more than X from the server. [say, 24hours or so]
Any trick?
Use session cookies. Not session in the meaning of PHP sessions, but browser session. Session cookies are stored until the user closes the browser. They are immune to whichever clock the user has set her computer. They will last until the browser is closed.
That is normally appropriate for PHP-session related cookies.
For PHP you need to ensure that the session cookie parameter lifetime is configured to 0 before the session starts. That is either the ini setting session.cookie_lifetime or by calling the session_set_cookie_params function.
For a more detailed description of cookie parameters, see the documentation of the setcookie function.
Second part of the trick is that you place a session start timestamp and a last activity timestamp into the PHP $_SESSION. Those are server based so have always the same base.
Check them, e.g. if the session is too old, last activity too long ago etc., destroy the session and force the user to login again.
You could even use that second part of the trick to combine it with a cookie that has it's expiry 10 years in the future (okay, browser might not like that, maybe you just want your three months).
Try to disable the session timeout or at least set it far into the future. That should do the trick.
I am using a simple bit of PHP code in my header file which increments a counter in my SQL database by 1 once per PHP session. I've tested this and it works fine.
However when I leave it for a day the counter has gone up by way more than I believe it should, and comparing this to the pageview counter in my Google Analytics it is far too high.
What could be happening and how could I stop this?
Google-analytics has a very different way of counting visits than a simple session based counter. I can't tell you exactly how it counts it because it is very closed source on that aspect but there is definitely cookies, sessions and javascript involved.
If you want my opinion. I built my own stat system once and it was hell with all those robots detection, trends, false visits. I switched to GA and it was worse because the client then started complaining that the numbers werent the same in both sites.
IMO? Don't use both, make up your own or use GA only, but not the two, you'll probably NEVER hit the same numbers.
Good luck
What do you mean by "once per session"?
You need to do a start_session() and then set a variable to ensure you are only counting unique sessions:
if(!isset($_SESSION['started'])) {
doHitCounter();
$_SESSION['started']=true;
}
Is it possible to run a function when the session ends on a PHP script? My script asks several questions and the user has 30 minutes to answer or the session expires. I would like my script to save any progress to a .txt file if the session expires and the user has not completed all the answers. How would I go about doing this?
I heard about register_shutdown_function('shutdown'); but I'm confused on where I would call it in my script.
My current script starts like this:
ini_set('session.gc_maxlifetime',1800);
ini_set('session.gc_probability',1);
ini_set('session.gc_divisor',1);
session_start();
if($_SESSION['loggedin'] !== 1) {//checks to see if user has logged in
header('Location: login.php');
exit;}
...asks a bunch of questions....
session_destroy();
Thanks for your help.
You have actually two options:
Save the progress when it happens (after every answer) and save information whether it has been completed. This solution works even if the browser has been closed (the progress is saved in real time).
Use AJAX to call the server every eg. 5 seconds and server should return information whether the session ended or not. If session ended, then do in JS what you need (even redirect to different page). This solution does not ensure saving the progress (the browser may be closed before action is made).
You can combine both options, depending on what you need and how your application works.
If page reloads after every answer (eg. reloads to show next question), then you can use option no. 1. If all the questions are on one page, choose option no. 2. If your application is combination of the two, you can choose both options.
EDIT:
Judging from your code, you are mixing:
session in terms of the time for answering questions with
session in terms of storing values between requests to the page in PHP.
The best idea is to separate the two. Give PHP session a much larger time limit, because it is needed for some other things such as actually showing progress or even saving progress. Instead, mark the time when the test began and store it in PHP session. This way after the time for the test is exhausted, you will be able to determine that and ignore any questions answered after that.
There's a couple of methods that come to mind immediately. You could use PHP's built in sleep method or you could use AJAX. Not saying these are the only ways, just the first ones that come to mind.
Edit: Now that I think about it, sleep probably isn't an option as it would exceed maximum run time and throw an error. Haven't tested to make sure, but seems logical. So AJAX is your best bet, assuming I'm not missing anything.
I'm trying to write a simple web chat app with PHP and AJAX.
I need to be aware of all the open sessions so that I can display a list of online users that are available to talk to. I also need to be aware of log outs because I use "both the sending and the receiving party are offline" as a condition for considering a chat session terminated and deleting the messages.
I'm keeping track of logged in users in a database: adding an entry on log-in and removing it on log-out works fine, but it's not comprehensive, as there are two other ways a user can become logged out:
server side session expires after inactivity.
client side cookie gets destroyed on browser close. Seems like a bad idea to use some sort of onclose triggered AJAX (what if the browser crashes or something?).
Simplest solution seems to be keeping a timestamp of last activity. I see some problems with this though:
AFAIK server-side expiry is chance based, so it wouldn't be accurate (and if I get the expiry time 3 minutes wrong, that's 3 minutes where some guy could be talking to an offline user wondering why no one is answering)
I'd have to constantly be querying the database to check every logged in users' last activity time compared to the current time. I don't see when / where I'd do this efficiently. It seems stupid to do this every single time the list of online users is needed.
Any help appreciated. I'm coding this myself because I'm not aware of any web chat frameworks that can integrate with my existing user database, do correct me if I'm wrong.
I don't think you're going to be able to do much to mitigate the constant querying to determine if users have logged off by closing the browser, internet connection issues, etc., but you could perhaps have each client make an AJAX request to the server every 5 seconds to update the last activity time, and have your application on the server consider the user "logged off" if they have missed 3-4 consecutive requests (ie, their last activity time is > 20 seconds).
On the client side, you could then check the last activity time every time your client sends a message to another user, and respond that they'd logged off if that had happened. If they attemped to open a chat with another user, you could also do an immediate call to check their status. Then you could perhaps check the status of all users in the user list every 30 seconds. That way your client gets pretty quick feedback if the person (s)he is chatting with drops offline unexpectedly.
You could invert your pattern, replacing your Ajax pull behavior with a push notification system.
In this way you can notify your chat users in realtime of login and logout of new chat members. I never did something like this in practice, but I've read about this kind of technology and it seems very interesting for cases like yours.
It's just a little bit harder than the ajax pull way, but once the main structure is implemented you can add functionality easily and the performance would be a lot better.
Some links I found that can be useful:
http://www.pubnub.com/blog/build-real-time-web-apps-easy
http://www.ape-project.org/
This is a railscast episode which deal with a javascript chat, the implementation is in rails, but even if you don't understand rails you should be able to follow it to get the core concepts: http://railscasts.com/episodes/260-messaging-with-faye
I'm not sure if you need both probability and divisor but here's what I do to auto logout people:
ini_set('session.gc_maxlifetime',3600); // 1 hour
ini_set('session.gc_probability',1); // it does garbage cleaning EVERY time
ini_set('session.gc_divisor',1); // it does garbage cleaning EVERY time
session_start();
Most of the data you are currently using and the data you need is stored in the PHP session - it's just not obvious how to derive the user id from the information.
If you switch to using a database bound session handler then it all becomes very easy. I had a quick google - and there are lots of examples out there. but a lot of them (e.g. this one) don't check for expiry on reading back the session. OTOH the example I've linked to does show adding the user id to the sesion record - which you'll need later. So the session read handler function should be something like:
read:
SELECT session_data, username
FROM sessions
WHERE session_id=' . session_id() . '
AND last_updated>= ' . date('YmdHis', time()-ini_get('session.gc_maxlifetime'))
And to get all the currently logged on users:
SELECT username
FROM sessions
WHERE last_updated>= ' . date('YmdHis', time()-ini_get('session.gc_maxlifetime'))
...and let the (overridden) session garbage collector automatically clear out redundant data.
HTH
First separate your concerns.
As far as 'list of online users' is concerned,you can use database & it seems you already have figured that out. (even if some one doesn't logs out properly,displaying a few extra online users won't do much damage)
Now for the chat app,for checking if a user is still online you will have to use ajax.
There is simply no other way.Of course there always can be a hack,I don't know.
see the image when you answer here (stackoverflow).it constantly checks if time has passed(& have you typed anything new) & saves a copy.
It seems that you are most concerned about performance and you have the implementation details figured out(mostly). Just change the type of the table that handles sessions to 'memory', this will reduce the performance cost of quering the db for every request to almost nothing as you are fetching data directly from RAM. Just make sure you delete the session every time a user explicity logs out, or you mark the user as inactive.
But no matter what you do implementing something that requires constant communication between client and server can never be done perfectly over HTTP. But if you put reasonable timeouts etc. it will work 99% of the time.
I am late to this party, but let me give my two cents.
In this particular scenario, there is no need for a push system for bad notifications. There is also no need for cron. Let me explain :
Say A,B and C are in a chat room & B's browser crashes, so his session expires. Right now , the server thinks B is still there but she is not. How do you update A & C? When A & C ASK for the update. Check B's last keepalive timestamp and figure out that their session has expired.
If all A,B & C crash, then this never happens I hear you ask. Who cares? There is no one to see our mistake now! The only downside is keeping up their chatroom alive which costs some database space. This can be cleaned up when another chat session is created.
A final gist :
Keep timestamps for the last time an action was taken.
Use a user event to loop through timestamps and take out the deadwood.
In case of users, this would be logging them out. In case of chatrooms, this would be those that have expired.
I am using codeigniter's session class to handle my PHP sessions. One of the session variables automatically created on every visit to the site is session_id:
The user's unique Session ID (this is a statistically random string with very strong entropy, hashed with MD5 for portability, and regenerated (by default) every five minutes)
On my site I need to have functionality to track unregistered user's and I currently have this implemented by comparing the visitor's session_id with a stored id value in a VISITOR table in the database. This works perfectly except for the fact that the session id times out every five minutes. I would like my application to remember visitors for longer than 5 minutes (kind of like what SO does when you post a question or answer without registering).
My question is this: can you see any security issues with simply extending the regeneration time of the session class (to something like 12 hours)?
Update: based on the answers I've seen so far, it seems like its more of a performance concern rather than a safety issue. Its kinda weird how the codeigniter session class works because when creating a new session, it also creates a new cookie which seems to persist as long as the session. I guess I could create another cookie with the session ID that lasts as long as I need it to. But how much of a performance concern would it be if I were to save the sessions for something like 12 hours? Would it slow things down unless I have millions of unique visitors within a 12 hour period (in which case I'd have bigger problems to worry about...)?
Two things with that idea :
If users go away from their computer (without locking it / closing their browser), someone else might use it to go to your site with their account
well, that's probably not your problem
if you have some login/password fields, your users probably already have their login+password memorized by the browser anyway (well, for the registedred ones, anyway -- and those probably have more "power" than not registered ones)
If you have lots of users on your site, you will have more session files
as sessions are stored in files
(same if they are stored in DB / memcached -- in which case you must ensure you have configured memcached so there is enough RAM to store more sessions)
So, yes, there is a small security risk ; but I don't think it is really relevant.
Another idea would be to keep a short session lifetime, but to store some informations in cookies, with a lifetime more important than that ?
Enough information, actually, to allow re-creation of a new session, without the user noticing anything ?
But, yes, that would require a bit more work on your side...
To add a bit more precisions after your edit :
Its kinda weird how the codeigniter
session class works because when
creating a new session, it also
creates a new cookie which seems to
persist as long as the session.
This is the "standard" way of dealing with sessions -- at least, in PHP :
The session's data is stored in a file, on disk, on the server
and a cookie is used to keep a "link" between a user, and the file containing his session's information. Without that cookie, there would be no way of knowing which one of those files contains the session of a specific user.
But how much of a performance concern
would it be if I were to save the
sessions for something like 12 hours?
If you're having millions of users on your site, this will means having millions of files, each one containing the session's data of one user -- and it's not good to have too many files.
But is you are having a few hundreds user, that should be allright, I guess.
Depending on the amount of visitors to your site, saving sessions for 12 hours may not be a good idea. Why not use cookies? This is dependent on whether or not the user has it enabled in his browser though: http://www.php.net/setcookie.
One Security Tip:
Leave True on sess_match_useragent(application/config/config.php)