473,543 Members | 2,455 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Setting a timeout for PHP sessions.

Atli
5,058 Recognized Expert Expert
Introduction
In this article I aim to explain the reasons why PHP sessions expire after a set period of inactivity, and how this mechanism works. I'll describe two commonly used methods to control the lifetime of a session, and show how to do so in your code.

The problem
PHP's session mechanism allows us to store data for clients on the server to make it persist through multiple requests. However, because the data itself is stored on the server, and the only thing connecting client's to their respective sessions on the server is a simple cookie, this creates a major security concern.

An exploit known as session hijacking is when a malicious third party intercepts or steals the session cookie from a client, and uses it to access the data from an active session. The server can do little to defend against this because it has no way to tell the original client from the hijacker.

The solution
The most important defense we have against this is to disregard sessions that have been inactive for a set period. This prevents hijackers from accessing sessions unless they are doing so in real-time, within the specified period.

In PHP the mechanism that implements this is known as the session garbage collector. Data files are tagged with a "last modified" time stamp, which PHP uses to determine when the client last used a session. If the session is older than the allowed lifetime of a session, it is destroyed. The default lifetime of a session in PHP is 1440 seconds, or 24 minutes.

We may find ourselves in situations where we would want to manually configure the session lifetime; to be able to better control the time-out period of a session. There are two ways we can do that:

Method #1: Code it manually
You can simply add a snippet of code to the top of every page on your site that sets a field in the session to the current time. You can then use that field to determine how long the session has stayed inactive for and act accordingly. For example:
Expand|Select|Wrap|Line Numbers
  1. session_start();
  2. $timeout = 60; // Number of seconds until it times out.
  3.  
  4. // Check if the timeout field exists.
  5. if(isset($_SESSION['timeout'])) {
  6.     // See if the number of seconds since the last
  7.     // visit is larger than the timeout period.
  8.     $duration = time() - (int)$_SESSION['timeout'];
  9.     if($duration > $timeout) {
  10.         // Destroy the session and restart it.
  11.         session_destroy();
  12.         session_start();
  13.     }
  14. }
  15.  
  16. // Update the timout field with the current time.
  17. $_SESSION['timeout'] = time();


Method #2: Reconfigure PHP's session garbage collection
The session.gc_maxl ifetime PHP.ini directive controls how long a session is allowed to exists before it is considered garbage and is cleaned up. Every call to the session_start() function has a chance to trigger the garbage collection routine.

The chance each call has to trigger the routine is determined by the session.gc_prob ability and session.gc_divi sor directives. The probability is calculated as:
- session.gc_prob ability / session.gc_divi sor

By default the values are 1 and 100, respectively, or a 1% chance that the garbage collector is triggered. If your site has low traffic, you should increase the value of session.gc_prob ability to increase the chance. If you want to guarantee that it will be triggered, set both directives to the same value.

Another thing to consider is the directory where PHP stores the session data. PHP applies the same lifetime to all session data files in the same directory; the lowest lifetime applies to them all. Meaning that if you want to be sure your session is timed out correctly, you need to be using your own directory. Best way to deal with that is to either create one in your home or temp directories. You can have PHP create the directory using the mkdir function, and you set the location by changing the session.save_pa th directive.

These values can be set using the ini_set function, so you can set the session garbage collection values on a per-request basis. For example, this function can be used to start a session and have it time out using a given time-out value:
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. /***
  3.  * Starts a session with a specific timeout and a specific GC probability.
  4.  * @param int $timeout The number of seconds until it should time out.
  5.  * @param int $probability The probablity, in int percentage, that the garbage 
  6.  *        collection routine will be triggered right now.
  7.  * @param strint $cookie_domain The domain path for the cookie.
  8.  */
  9. function session_start_timeout($timeout=5, $probability=100, $cookie_domain='/') {
  10.     // Set the max lifetime
  11.     ini_set("session.gc_maxlifetime", $timeout);
  12.  
  13.     // Set the session cookie to timout
  14.     ini_set("session.cookie_lifetime", $timeout);
  15.  
  16.     // Change the save path. Sessions stored in teh same path
  17.     // all share the same lifetime; the lowest lifetime will be
  18.     // used for all. Therefore, for this to work, the session
  19.     // must be stored in a directory where only sessions sharing
  20.     // it's lifetime are. Best to just dynamically create on.
  21.     $seperator = strstr(strtoupper(substr(PHP_OS, 0, 3)), "WIN") ? "\\" : "/";
  22.     $path = ini_get("session.save_path") . $seperator . "session_" . $timeout . "sec";
  23.     if(!file_exists($path)) {
  24.         if(!mkdir($path, 600)) {
  25.             trigger_error("Failed to create session save path directory '$path'. Check permissions.", E_USER_ERROR);
  26.         }
  27.     }
  28.     ini_set("session.save_path", $path);
  29.  
  30.     // Set the chance to trigger the garbage collection.
  31.     ini_set("session.gc_probability", $probability);
  32.     ini_set("session.gc_divisor", 100); // Should always be 100
  33.  
  34.     // Start the session!
  35.     session_start();
  36.  
  37.     // Renew the time left until this session times out.
  38.     // If you skip this, the session will time out based
  39.     // on the time when it was created, rather than when
  40.     // it was last used.
  41.     if(isset($_COOKIE[session_name()])) {
  42.         setcookie(session_name(), $_COOKIE[session_name()], time() + $timeout, $cookie_domain);
  43.     }
  44. }
To set a one minute timeout on a session, you could call the above function like so:
Expand|Select|Wrap|Line Numbers
  1. session_start_timeout(60);
By default, it sets a 100% chance the GC routine triggers. On a high traffic site that could put strain on the server. To fix that, you could lower the chance by passing the percentage you want in the second parameter:
Expand|Select|Wrap|Line Numbers
  1. session_start_timeout(60, 10);
This gives it a 10% chance to trigger the GC routine.

Epilogue
If you have any questions or comments about the article, feel free to leave a reply. If you need help fixing specific problems, I urge you to post a new question in the PHP answers forum, where the entire community will do it's best to help you out.

All the best,
- Atli
Jun 7 '10 #1
4 144328
erikschoel
1 New Member
Very nice. Clear and concise. Thanks!
Mar 14 '12 #2
tamaghna1991
1 New Member
I want to destroy a session when there is no user activity up to some amount of time say 15 minutes, how i could make a session that checks whether there is any key press event or not??
Aug 11 '14 #3
Atli
5,058 Recognized Expert Expert
If you want to monitor what's happening on the browser, that would require JavaScript. PHP can't interact with the browser, aside from generating the initial HTTP response content.

The first step of this would be to set the session mechanism up so it destroys the session after your desired timeout period. My above post explains how that works.

The second step - if you want every key and mouse interaction to refresh the session timeout - would be to use JavaScript to listen for all key and mouse events. It should be sufficient to listen for "keydown" and "mousemove" events on the document object. - In that listener, you'd then want to "ping" the PHP code with an AJAX request, so that it will keep the session alive on the server. What I mean by that is: set up a PHP script who's only purpose is to refresh the session, and then have JavaScript request that script on events.

Also, to avoid flooding the server with pings, when your users are typing rapidly or moving the mouse around a lot, you'd want to take measures to make sure AJAX requests aren't being sent tens or hundreds of times per second. (Which can easily happen with the mousemove event.) Make sure you keep track of when AJAX requests are being fired, and that it's only happening once every few seconds.


One more thing. JavaScript event propagation is a bit of a tricky thing, and it is possible to stop events from reaching the document object. If you do that anywhere in your code (or are using poorly built plugins!) then the affected events won't refresh the session.
Aug 13 '14 #4
colon
1 New Member
Merry Christmas!
I tried this code to check timeout, but always get the same session id:
Expand|Select|Wrap|Line Numbers
  1. print session_name();
Is this normal?
Dec 26 '14 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

1
4928
by: Andras Kovacs | last post by:
I have a "insert into" transaction that hangs because there is a lock on the table and one of its rows. (Advanced syncron replication causes this locking problem.) Unfortunately adv replication is not perfectly aware of locks. The transaction hangs for 60 seconds thant stops with an ORA-02949 error. Is there a way to change the default...
2
4585
by: - | last post by:
Hi there All, Don't know if this is possible at all, but here goes. I've got a page (an active server page if that makes any difference), that is pulling some sticky content from www.freesticky.com using the following code: <script type="text/JavaScript" src="http://www.freesticky.com/stickyweb/syndicate/otd_events_hlines.asp"></
4
11799
by: Joseph | last post by:
I have an intranet application that I setup using windows authentication through IIS basic authentication. Is there a way to set a timeout, so that after ten minutes the user will be prompted again to enter their login ID and password? I have not been able to find anything on microsoft or google. Other than this, the only way a user will...
1
3368
by: ArunPrakash | last post by:
Hi, I want to implement a method which will poll database for messages. But i want to provide a method that will specify a timeout until which it will be polled and after that it will throw an exception. I tried the following code. Here say for example GetString in class test is a method for which i want to provide timeout. Class1 contains...
1
2878
by: Scott Walters | last post by:
Hi, I have an asp.net webapp that uses some javascript in a hidden frame on the browser to poll the server every 30 seconds, using an http post. I also want my sessions to timeout in the normal fashion. The way I'm trying to get around this is by manually setting the timeout property for the session. I cache the starting session...
2
2153
by: Swaroop | last post by:
PLS HELP..I am working on socket programming as part of my final year project. I want to know how to set a timeout on read api that reads from a socket. Is it possible using SIGALRM signal?Will setting O_NONBLOCK flag of the socket help? Is there any other way to do it?
1
1773
by: Ramakrishnan Nagarajan | last post by:
Hi, In my application I am using several Stored Procedures written in MS-Sql Server. Of that one SP takes much time to execute. Because of that, one of my pages using that SP is throwing Timeout Expired Error. The SP is optimized is the saying by my DB Team. So now I need to counter that error in my page only. Is there any possible approach...
1
1795
by: Young | last post by:
I am getting timeout problem in my VB.NET app. I've set the timeout value in webconfig and machine.config file and also set it within the application and still my app. timeout sooner that expected. Can anyone please help? Tks Y
2
14330
by: SriBhargav | last post by:
Hi, I've a question on setting timeout on console.readline() I would like the user to input something through Console.readline() in 5 secs. If there is no input in that time, I would like to proceed further with the program logic. I had a difficulty in implementing this, as console.readline() indefinitely waits for the user input.
2
2189
by: Kong Chun Ho | last post by:
Hello, I have a problem on setting timeout in for loop. Here is my code: function setOpacity (elem, val) { var z = document.getElementById(elem); z.style.opacity=val/100; z.style.filter = "alpha(opacity=" + val + ")";
0
7341
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7584
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7729
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7332
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
5880
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5258
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
4884
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3385
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
952
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.