Jump to content

[SOLVED] Session error, variables not being set? hard to reproduce


xtopolis

Recommended Posts

Unfortunately this is hard to reproduce... but:

 

Usually upon first going to my main page (a login form), if I haven't been there in over a half hour (most likely, inactive since the session expiry timelimit), I will submit the form, only to have it redirect back as if the login was bad (even when using valid credentials).

 

I set up debug messages, and it points to a session variable that should be being set failing as not being set.  However, I cannot pinpoint why this happens sometimes, but not others.  This happens on multiple PCs, but not every time unfortunately.

 

Is there some quirky thing I'm not aware of where session vars are not always set?

 

 

-All pages call the session class, which constructs as simply: session_start();

-The session is not being instantiated more than one per page (i have E_NOTICE on)

 

Relevant code~

(index.php[form]->login.php[check via db]->login.php?do=cpw[verify access via session var, so users must have a valid login before being allowed to the change pw page])

 

login.php

<?php
  require 'engine/config.php';

switch(true)
{
  //logout if requested
  case (isset($_GET['do']) && $_GET['do'] == 'logout'):
    $user = &new User($db,SECRET,true);
    break;

//--------------------------------------------------------------------------

  //request change password
  case (isset($_GET['do']) && $_GET['do'] == 'cpw'):
    $session=new Session();
    $un = $session->get('rcpw_un');
      
      //require session(un) to be set from login before instantiating
      if(!$un) {
        $session->set('login_error','Please login before accessing that page.');
        header('Location: ./index.php');
      }
    
    $rcpw = &new RCPW($un,$session);
    break;

//--------------------------------------------------------------------------

  //regular login
  default:
    $user = &new User($db,SECRET);
    break;

}//switch
?>

 

excerpt from user.php

<?php
//construct exerpt
    $this->session = new Session();
// ... later
    switch($row['RCPW'])
    {
      case '1'://Require password change
          $this->session->set('rcpw_un',$this->un);
          header('Location: '.STARTURL.'login.php?do=cpw');
        break;
?>

I am under the impression that a session_start() call needs only be placed before session variables are accessed, or content has been output to the page (ie, session_start called in the same manner as a header would be, before content is output).

 

Is this not correct?

 

Also, if I needed session_start() at the top, not as an include, that should mean that it would not work at all, right?[but it works 99% of the time]

The only requirement is that any page that uses sessions must have a session_start() prior to any content has been sent to the browser. Content is anything that is not a header. The session_start() can be in any code on the page and php code included through the file system is the same as any other code on the page.

 

The 24 minuted limit is caused by the the session garbage collection running and deleting session data files with a last access time greater than the session.gc_maxlifetime setting (the default is 1440 seconds, 24 minutes.) The key to this is the last access time. If you are on a page, like a form, and no http request is sent to the web server, the session data file is not accessed and it keeps getting older and older. Some people use AJAX to "ping" a page on the server that does a session_start() to keep the session data file's last access time current.

 

If this is your web server, you can simply change the session.gc_maxlifetime setting in your php.ini and stop and start the web server to get the change to take effect.

 

On a shared web server, you must do two things. The first is to set the session.gc_maxlifetime setting before every session_start. You can do this in a .htaccess file (when php is running as an Apache module), in a local php.ini (when php is running as a CGI application), or in your script. The second thing is to set the session.save_path setting to be to a private folder within your account's disk space. The second step is needed so that when session garbage collection runs due to the other scripts on the server and they use their session.gc_maxlifetime setting (or the default one), they don't cause your session data files to be deleted.

@PFMaBiSmAd

 

I am on a shared web server.

Your explanation makes sense for the most part, and it's entirely possible that the other users of the shared server are inadvertently causing my sessions to not be ..perfect.. for lack of a better word.

 

The final production environment will be on a private server, but I assume setting a custom save_path and maxlifetime won't affect anything in the long run. However, is it not safe to assume I could avoid this situation on the shared server by using a database for session handling?

 

I plan to rework my page(s) a little anyway, because there is a small security risk of having a session started on a login page where no authentication has taken place, it has been pointed out to me.

 

Any other thoughts?  I am marking this solved, since it answered my main Qs.  Thanks.

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.