473,395 Members | 1,608 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes and contribute your articles to a community of 473,395 developers and data experts.

Setting a timeout for PHP sessions.

Atli
5,058 Expert 4TB
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_maxlifetime 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_probability and session.gc_divisor directives. The probability is calculated as:
- session.gc_probability / session.gc_divisor

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_probability 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_path 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 144195
Very nice. Clear and concise. Thanks!
Mar 14 '12 #2
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 Expert 4TB
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
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
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...
2
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...
4
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...
1
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...
1
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...
2
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...
1
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...
1
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...
2
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...
2
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...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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...
0
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.