title: jQuery AJAX PHP OOP Login Loses SESSION after login
body: <p>I have an object oriented PHP login system that logs in the user sucessfully using jQuery AJAX, but upon redirection the a new web page (or the return URL), the $SESSION information is lost. What is wrong with the coding?</p>
  
  <p><strong>EDIT/UPDATE:</strong> I found this issue occurs on any page when I assign or view / echo a $_SESSION variable. Something is not right. This is a copy of my php.ini file for SESSIONS.</p>
  
  <pre><code>[Session]
  ; Handler used to store/retrieve data.
  ; http://php.net/session.save-handler
  session.save_handler = files
  
  ; Argument passed to save_handler.  In the case of files, this is the path
  ; where data files are stored. Note: Windows users have to change this
  ; variable in order to use PHP's session functions.
  ;
  ; The path can be defined as:
  ;
  ;     session.save_path = "N;/path"
  ;
  ; where N is an integer.  Instead of storing all the session files in
  ; /path, what this will do is use subdirectories N-levels deep, and
  ; store the session data in those directories.  This is useful if you
  ; or your OS have problems with lots of files in one directory, and is
  ; a more efficient layout for servers that handle lots of sessions.
  ;
  ; NOTE 1: PHP will not create this directory structure automatically.
  ;         You can use the script in the ext/session dir for that purpose.
  ; NOTE 2: See the section on garbage collection below if you choose to
  ;         use subdirectories for session storage
  ;
  ; The file storage module creates files using mode 600 by default.
  ; You can change that by using
  ;
  ;     session.save_path = "N;MODE;/path"
  ;
  ; where MODE is the octal representation of the mode. Note that this
  ; does not overwrite the process's umask.
  ; http://php.net/session.save-path
  session.save_path = "/var/php_sessions"
  
  ; Whether to use cookies.
  ; http://php.net/session.use-cookies
  session.use_cookies = 1
  
  ; http://php.net/session.cookie-secure
  ;session.cookie_secure =
  
  ; This option forces PHP to fetch and use a cookie for storing and maintaining
  ; the session id. We encourage this operation as it's very helpful in combating
  ; session hijacking when not specifying and managing your own session id. It is
  ; not the end all be all of session hijacking defense, but it's a good start.
  ; http://php.net/session.use-only-cookies
  session.use_only_cookies = 1
  
  ; Name of the session (used as cookie name).
  ; http://php.net/session.name
  session.name = PHPSESSID
  
  ; Initialize session on request startup.
  ; http://php.net/session.auto-start
  session.auto_start = 1
  
  ; Lifetime in seconds of cookie or, if 0, until browser is restarted.
  ; http://php.net/session.cookie-lifetime
  session.cookie_lifetime = 0
  
  ; The path for which the cookie is valid.
  ; http://php.net/session.cookie-path
  session.cookie_path = /
  
  ; The domain for which the cookie is valid.
  ; http://php.net/session.cookie-domain
  session.cookie_domain =
  
  ; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript.
  ; http://php.net/session.cookie-httponly
  session.cookie_httponly =
  
  ; Handler used to serialize data.  php is the standard serializer of PHP.
  ; http://php.net/session.serialize-handler
  session.serialize_handler = php
  
  ; Defines the probability that the 'garbage collection' process is started
  ; on every session initialization. The probability is calculated by using
  ; gc_probability/gc_divisor. Where session.gc_probability is the numerator
  ; and gc_divisor is the denominator in the equation. Setting this value to 1
  ; when the session.gc_divisor value is 100 will give you approximately a 1% chance
  ; the gc will run on any give request.
  ; Default Value: 1
  ; Development Value: 1
  ; Production Value: 1
  ; http://php.net/session.gc-probability
  session.gc_probability = 1
  
  ; Defines the probability that the 'garbage collection' process is started on every
  ; session initialization. The probability is calculated by using the following equation:
  ; gc_probability/gc_divisor. Where session.gc_probability is the numerator and
  ; session.gc_divisor is the denominator in the equation. Setting this value to 1
  ; when the session.gc_divisor value is 100 will give you approximately a 1% chance
  ; the gc will run on any give request. Increasing this value to 1000 will give you
  ; a 0.1% chance the gc will run on any give request. For high volume production servers,
  ; this is a more efficient approach.
  ; Default Value: 100
  ; Development Value: 1000
  ; Production Value: 1000
  ; http://php.net/session.gc-divisor
  session.gc_divisor = 1000
  
  ; After this number of seconds, stored data will be seen as 'garbage' and
  ; cleaned up by the garbage collection process.
  ; http://php.net/session.gc-maxlifetime
  session.gc_maxlifetime = 1440
  
  ; NOTE: If you are using the subdirectory option for storing session files
  ;       (see session.save_path above), then garbage collection does *not*
  ;       happen automatically.  You will need to do your own garbage
  ;       collection through a shell script, cron entry, or some other method.
  ;       For example, the following script would is the equivalent of
  ;       setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
  ;          find /path/to/sessions -cmin +24 | xargs rm
  
  ; PHP 4.2 and less have an undocumented feature/bug that allows you to
  ; to initialize a session variable in the global scope, even when register_globals
  ; is disabled.  PHP 4.3 and later will warn you, if this feature is used.
  ; You can disable the feature and the warning separately. At this time,
  ; the warning is only displayed, if bug_compat_42 is enabled. This feature
  ; introduces some serious security problems if not handled correctly. It's
  ; recommended that you do not use this feature on production servers. But you
  ; should enable this on development servers and enable the warning as well. If you
  ; do not enable the feature on development servers, you won't be warned when it's
  ; used and debugging errors caused by this can be difficult to track down.
  ; Default Value: On
  ; Development Value: On
  ; Production Value: Off
  ; http://php.net/session.bug-compat-42
  session.bug_compat_42 = Off
  
  ; This setting controls whether or not you are warned by PHP when initializing a
  ; session value into the global space. session.bug_compat_42 must be enabled before
  ; these warnings can be issued by PHP. See the directive above for more information.
  ; Default Value: On
  ; Development Value: On
  ; Production Value: Off
  ; http://php.net/session.bug-compat-warn
  session.bug_compat_warn = Off
  
  ; Check HTTP Referer to invalidate externally stored URLs containing ids.
  ; HTTP_REFERER has to contain this substring for the session to be
  ; considered as valid.
  ; http://php.net/session.referer-check
  session.referer_check =
  
  ; How many bytes to read from the file.
  ; http://php.net/session.entropy-length
  session.entropy_length = 0
  
  ; Specified here to create the session id.
  ; http://php.net/session.entropy-file
  ; On systems that don't have /dev/urandom /dev/arandom can be used
  ; On windows, setting the entropy_length setting will activate the 
  ; Windows random source (using the CryptoAPI)
  session.entropy_file = /dev/urandom
  
  ; Set to {nocache,private,public,} to determine HTTP caching aspects
  ; or leave this empty to avoid sending anti-caching headers.
  ; http://php.net/session.cache-limiter
  session.cache_limiter = nocache
  
  ; Document expires after n minutes.
  ; http://php.net/session.cache-expire
  session.cache_expire = 180
  
  ; trans sid support is disabled by default.
  ; Use of trans sid may risk your users security.
  ; Use this option with caution.
  ; - User may send URL contains active session ID
  ;   to other person via. email/irc/etc.
  ; - URL that contains active session ID may be stored
  ;   in publicly accessible computer.
  ; - User may access your site with the same session ID
  ;   always using URL stored in browser's history or bookmarks.
  ; http://php.net/session.use-trans-sid
  session.use_trans_sid = 1
  
  ; Select a hash function for use in generating session ids.
  ; Possible Values
  ;   0  (MD5 128 bits)
  ;   1  (SHA-1 160 bits)
  ; This option may also be set to the name of any hash function supported by
  ; the hash extension. A list of available hashes is returned by the hash_algos()
  ; function.
  ; http://php.net/session.hash-function
  session.hash_function = 0
  
  ; Define how many bits are stored in each character when converting
  ; the binary hash data to something readable.
  ; Possible values:
  ;   4  (4 bits: 0-9, a-f)
  ;   5  (5 bits: 0-9, a-v)
  ;   6  (6 bits: 0-9, a-z, A-Z, "-", ",")
  ; Default Value: 4
  ; Development Value: 5
  ; Production Value: 5
  ; http://php.net/session.hash-bits-per-character
  session.hash_bits_per_character = 4
  
  ; The URL rewriter will look for URLs in a defined set of HTML tags.
  ; form/fieldset are special; if you include them here, the rewriter will
  ; add a hidden &lt;input&gt; field with the info which is otherwise appended
  ; to URLs.  If you want XHTML conformity, remove the form entry.
  ; Note that all valid entries require a "=", even if no value follows.
  ; Default Value: "a=href,area=href,frame=src,form=,fieldset="
  ; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
  ; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
  ; http://php.net/url-rewriter.tags
  url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=,fieldset="
  </code></pre>
  
  <p>I have the initial log in page login. php (that also contains the jQuery AJAX)
  login.php</p>
  
  <pre><code>&lt;?php
  
      session_start();
  ?&gt;
  &lt;html&gt;
      &lt;head&gt;
                  &lt;script type="text/javascript" src="http://static.fluxexchange.com/fluxexchange/js/jquery-1.8.3.min.js"&gt;&lt;/script&gt;
  
      &lt;/head&gt;
      &lt;body&gt;
          &lt;form action="" id="login" class="network_login" onSubmit="return false;"&gt;
                                  &lt;h3&gt;Sign in to share your cultures and interests with friends.&lt;/h3&gt;
                                  &lt;div&gt;
                                  &lt;label&gt;Handle, Email, or Phone&lt;/label&gt;&lt;input name="handle" id="login-handle" class="login_input"&gt;
                                  &lt;/div&gt;
                                  &lt;div&gt;
                                  &lt;label&gt;Passcode&lt;/label&gt;&lt;input name="password" id="login-password" class="login_input" type="password"&gt;
                                  &lt;/div&gt;
                                  &lt;div&gt;
                                  &lt;input class="auto-authenticate" type="checkbox" style="border:0px;"&gt;&lt;label style="width:auto;"&gt;Keep me authenticated&lt;/label&gt;
                                  &lt;/div&gt;
                                  &lt;?php
                                      $iredirect_url=$_GET['return_url'];
                                  ?&gt;
                                  &lt;input type="hidden" name="return_url" value="&lt;?php echo $iredirect_url; ?&gt;"&gt;
  
                                  &lt;label id="login_submit_button" class="login_button"&gt;
                                      &lt;input class="login-button-blue" value="Authenticate" type="submit"&gt;
                                  &lt;/label&gt;
                                  &lt;div id="login-loader" class="loader"&gt;&lt;/div&gt;
                                  &lt;span class="login-option" id="more-login-options"&gt;I'm looking for more login options.&lt;/span&gt;
                              &lt;/form&gt;
                $(function(){
      $("#login-loader").hide();
      $("#login-success-notification").hide();
      $("#login_submit_button").click(function(){
          $("#login-loader").fadeIn(1000);
          authenticateUser();
      });
  });
  function authenticateUser(){
  
      $.ajax({
          type:"POST",
          url:"engine/authenticate_user.php",
          cache:false,
          data: $("#login").serialize(),
          dataType:"json",
          async:false,
          success: function(resp){
  
              console.log(resp);
  
              $('.reg-error-notification').empty();
              $('.reg-error-notification').hide();
  
  
              if(resp.logged_in=="true"){
                  $("#login-success-notification").append('&lt;p&gt;'+resp.session_test+'&lt;/p&gt;').fadeIn(1000, function(){
                      window.location.href=resp.return_url;
                  });
  
              } else {
                  $("#login-loader").fadeOut(1000);
                  $('#login-error-notification').append('&lt;p&gt;The handle you entered is incorrect. Please try again.&lt;/p&gt;').fadeIn(1000);
              }
          },
      });
  }
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>and index.php (where the login was redirected to when the issue occurred.</p>
  
  <pre><code>&lt;?
      session_start();
          print_r($_SESSION['network_id']);   
  
  ?&gt;
  </code></pre>
  
  <p>and authenticate_user.php</p>
  
  <pre><code>&lt;?php
      session_start();
      require("login-classes.php");
  
      $Authenticate= new Authenticate($_POST['handle'], $_POST['password'], $_POST['network'], $_POST['fenetwork']);
      $Authenticate-&gt;authenticateUser();
  
      $result=array();
      if($Authenticate-&gt;isLoggedIn()){
  
          $result['logged_in']="true";
          $result['return_url']=($_POST['return_url']);
          $result['session_test']=$_SESSION['network_id'];
      } else {
  
          $result['logged_in']="false";
      }
  
      echo json_encode($result);
  ?&gt;
  </code></pre>
  
  <p>login-classes.php (included in authenticate_user.php)</p>
  
  <pre><code> &lt;?php
          //(C) Flux Exchange Network, Inc.
          require ("database-classes.php");
  
          class Authenticate {
  
              public function __construct($username, $password, $network_site, $parent_network) {
  
                  $this-&gt;handle=$username;
                  $this-&gt;password=crypt($password, $this-&gt;salt);
                  $this-&gt;parent_network=$parent_network;
                  $this-&gt;network_site=$network_site;          
              }
  
              public function authenticateUser(){
                  $database=new Database();
                  $database-&gt;getConnection();
                  $database-&gt;startConnection();
  
                  $authenticate_q=mysql_query("SELECT network_users.network_id
                  FROM network_users
                  WHERE network_users.handle = '$this-&gt;handle'
                  AND network_users.password ='$this-&gt;password'
                  LIMIT 1");
  
                  if(mysql_num_rows($authenticate_q)==1){
  
                      $this-&gt;isLoggedIn=true;
                      $user=mysql_fetch_array($authenticate_q);
                      $this-&gt;network_id=$user['network_id'];
                      $this-&gt;setNetworkId();
                  } else{
                      //header('HTTP/1.1 500 Internal Server Error');
                      //die("Something went wrong.");
                  }
              }
  
              function isLoggedIn(){
  
                  return $this-&gt;isLoggedIn;
              }
  
              function addError($error){
  
                  $this-&gt;error_list[]=$error;
              }
  
  
              function setNetworkId(){
  
                  $_SESSION['network_id']=$this-&gt;network_id;
              }
  
              private $network_id, $handle, $password, $network_site, $parent_network, $error_list, $isLoggedIn=false,
              $salt="PRIVATE INFO";
          }
      ?&gt;
  </code></pre>