Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You should implement a session timeout of your own. Both options mentioned by others (<a href="http://php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime" rel="noreferrer"><em>session.gc_maxlifetime</em></a> and <a href="http://php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime" rel="noreferrer"><em>session.cookie_lifetime</em></a>) are not reliable. I'll explain the reasons for that.</p> <p><strong>First:</strong></p> <blockquote> <p><strong>session.gc_maxlifetime</strong><br> <em>session.gc_maxlifetime</em> specifies the number of seconds after which data will be seen as 'garbage' and cleaned up. Garbage collection occurs during session start.</p> </blockquote> <p>But the garbage collector is only started with a probability of <a href="http://php.net/manual/en/session.configuration.php#ini.session.gc-probability" rel="noreferrer"><em>session.gc_probability</em></a> divided by <a href="http://php.net/manual/en/session.configuration.php#ini.session.gc-divisor" rel="noreferrer"><em>session.gc_divisor</em></a>. And using the default values for those options (1 and 100 respectively), the chance is only at 1%.</p> <p>Well, you could simply adjust these values so that the garbage collector is started more often. But when the garbage collector is started, it will check the validity for every registered session. And that is cost-intensive.</p> <p>Furthermore, when using PHP's default <a href="http://php.net/manual/en/session.configuration.php#ini.session.save-handler" rel="noreferrer"><em>session.save_handler</em></a> files, the session data is stored in files in a path specified in <a href="http://php.net/manual/en/session.configuration.php#ini.session.save-path" rel="noreferrer"><em>session.save_path</em></a>. With that session handler, the age of the session data is calculated on the file's last modification date and not the last access date:</p> <blockquote> <p><strong>Note:</strong> If you are using the default file-based session handler, your filesystem must keep track of access times (atime). Windows FAT does not so you will have to come up with another way to handle garbage collecting your session if you are stuck with a FAT filesystem or any other filesystem where atime tracking is not available. Since PHP 4.2.3 it has used mtime (modified date) instead of atime. So, you won't have problems with filesystems where atime tracking is not available.</p> </blockquote> <p>So it additionally might occur that a session data file is deleted while the session itself is still considered as valid because the session data was not updated recently.</p> <p><strong>And second:</strong></p> <blockquote> <p><strong>session.cookie_lifetime</strong><br> <em>session.cookie_lifetime</em> specifies the lifetime of the cookie in seconds which is sent to the browser. […]</p> </blockquote> <p>Yes, that's right. This only affects the cookie lifetime and the session itself may still be valid. But it's the server's task to invalidate a session, not the client. So this doesn't help anything. In fact, having <em>session.cookie_lifetime</em> set to <code>0</code> would make the session’s cookie a real <a href="http://en.wikipedia.org/wiki/HTTP_cookie#Session_cookie" rel="noreferrer">session cookie</a> that is only valid until the browser is closed.</p> <p><strong>Conclusion / best solution:</strong></p> <p>The best solution is to implement a session timeout of your own. Use a simple time stamp that denotes the time of the last activity (i.e. request) and update it with every request:</p> <pre><code>if (isset($_SESSION['LAST_ACTIVITY']) &amp;&amp; (time() - $_SESSION['LAST_ACTIVITY'] &gt; 1800)) { // last request was more than 30 minutes ago session_unset(); // unset $_SESSION variable for the run-time session_destroy(); // destroy session data in storage } $_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp </code></pre> <p>Updating the session data with every request also changes the session file's modification date so that the session is not removed by the garbage collector prematurely.</p> <p>You can also use an additional time stamp to regenerate the session ID periodically to avoid attacks on sessions like <a href="http://www.owasp.org/index.php/Session_fixation" rel="noreferrer">session fixation</a>:</p> <pre><code>if (!isset($_SESSION['CREATED'])) { $_SESSION['CREATED'] = time(); } else if (time() - $_SESSION['CREATED'] &gt; 1800) { // session started more than 30 minutes ago session_regenerate_id(true); // change session ID for the current session and invalidate old session ID $_SESSION['CREATED'] = time(); // update creation time } </code></pre> <p><strong>Notes:</strong></p> <ul> <li><code>session.gc_maxlifetime</code> should be at least equal to the lifetime of this custom expiration handler (1800 in this example);</li> <li>if you want to expire the session after 30 minutes of <em>activity</em> instead of after 30 minutes <em>since start</em>, you'll also need to use <code>setcookie</code> with an expire of <code>time()+60*30</code> to keep the session cookie active.</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload