title: Sessions in AngularJS and PHP application
body: <p>I have an AngularJS application that I am updating to use PHP 7. Currently I have a custom session handler setup for sessions: </p>
  
  <h3>Custom Session Handler (session.php)</h3>
  
  <pre><code>function sess_open( $path, $name ) {
      return true;
  }
  
  function sess_close( ) {
      $sessionId = session_id(); 
      return true;
  }
  
  function sess_read( $id ) {
      $db = dbConn::getConnection();
  
      $stmt = "SELECT session_data FROM session where session_id =" . $db-&gt;quote($id);
      $result = $db-&gt;query($stmt);
      $data = $result-&gt;fetchColumn();
      $result-&gt;closeCursor();
      return $data;
  }
  
  function sess_write( $id, $data ) {
      $db = dbConn::getConnection();
  
      $tstData = sess_read( $id );
      if (!is_null($tstData)) {
          // if it does then do an update
          $stmt = "UPDATE session SET session_data =" . $db-&gt;quote($data) . " WHERE session_id=" . $db-&gt;quote($id);
          $db-&gt;query($stmt);
      }
      else {
          // else do an insert
          $stmt = "INSERT INTO session (session_id, session_data) SELECT ". $db-&gt;quote($id) . ", ". $db-&gt;quote($data) . " WHERE NOT EXISTS (SELECT 1 FROM session WHERE session_id=" . $db-&gt;quote($id) . ")";
          $db-&gt;query($stmt);
      }
  
      return true;
  }
  
  function sess_destroy( $id ) {
  
      $db = dbConn::getConnection();
  
      $stmt = "DELETE FROM session WHERE session_id =" . $db-&gt;quote($id);
      setcookie(session_name(), "", time() - 3600);
      return $db-&gt;query($stmt);
  }
  
  function sess_gc( $lifetime ) {
  
      $db = dbConn::getConnection();
  
      $stmt = "DELETE FROM session WHERE timestamp &lt; NOW() - INTERVAL '" . $lifetime . " second'";
      return $db-&gt;query($stmt);
  }
  
  session_name('PROJECT_CUPSAW_WEB_APP');
  session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
  session_start();
  ob_flush();
  </code></pre>
  
  <hr>
  
  <p>In my <code>app.js</code> I have a continuous check to see if the user is authenticated and can access the application. </p>
  
  <h3>App.js</h3>
  
  <pre><code>/*
   * Continuous check for authenticated permission to access application and route
   */
  app.run(function($rootScope, $state, authenticationService, ngToast) {
      $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
          authenticationService.isAuthenticated()
              .success(function () {
                  if(toState.permissions) {
                      ngToast.dismiss();
                      event.preventDefault();
                      $state.go("logout"); // NEEDS TO CHANGE - Unauthorized access view
                      return;
                  }
              })
              .error(function () {
                  ngToast.dismiss();
                  event.preventDefault();
                  localStorage.clear();
                  $state.go("authentication"); // User is not authenticated; return to login view
                  return;
              });
          ngToast.dismiss();
      });
  });
  </code></pre>
  
  <p>In the code above, <code>isAuthenticated</code> runs <code>isUserAuthorized.php</code> </p>
  
  <h3>isAuthenticated</h3>
  
  <pre><code>/*
   * Check if user is authenticated; set role/permissions
   */
  this.isAuthenticated = function() {
      return $http.post(baseUrl + '/isUserAuthorized.php');
  };
  </code></pre>
  
  <h3>isUserAuthorized.php</h3>
  
  <pre><code>&lt;?php
  
  require_once 'session.php';
  // Check to ensure user is authenticated to initiate request
  if (array_key_exists('authenticated', $_SESSION) &amp;&amp; $_SESSION['authenticated']) {
      return http_response_code(200);
  } else {
      // Clear out all cookies and destroy session
      if( array_key_exists('HTTP_COOKIE', $_SERVER)){
        $cookies = explode(';', $_SERVER['HTTP_COOKIE']);
        foreach($cookies as $cookie) {
            $parts = explode('=', $cookie);
            $name = trim($parts[0]);
            setcookie($name, '', time()-1000);
            setcookie($name, '', time()-1000, '/');
        }
      }
      session_destroy();
  
      return http_response_code(401);
  }
  </code></pre>
  
  <p>The session should be started when <code>session.php</code> is required. It appears that this is not happening though. Upon accessing the application, the login page is displayed, but <code>isUserAuthorized.php</code> is throwing a warning: </p>
  
  <blockquote>
    <p>Warning: session_start(): Failed to read session data: user (path: /var/lib/php/mod_php/session) in session.php </p>
  </blockquote>
  
  <p>When I select the <code>Login</code> button, <code>login.php</code> is called, but the user gets brought right into the application, despite incorrect credentials.  </p>
  
  <h3>login.php</h3>
  
  <pre><code>&lt;?php
  
  require_once '../database.php';
  require_once 'session.php';
  require_once 'ldap.php';
  
  $_SESSION['authenticated'] = false;
  
  //$conn = connect_db();
  
  try {
  
      $data = json_decode(file_get_contents('php://input'));
  
      $username = strtolower($data-&gt;username);
      $password = $data-&gt;password;
  
      // Check domain credentials; return user token if verified
      if(ldap_authenticate($username, $password)) {
          $_SESSION['authenticated'] = true;
      }
      else {
          echo('Invalid username and/or password!');
          return http_response_code(400);
      }
  }
  
  catch(PDOException $e) {
      return http_response_code(400);
  }
  </code></pre>
  
  <p>I'm not entirely sure what's causing this odd behavior, and why the session isn't being created.  Do I need to explicitly call the <code>sess_write</code> function? </p>
  
  <hr>
  
  <h1>Update</h1>
  
  <p>I discovered that removing the <code>require_once 'session.php'</code> from <code>login.php</code> causes the proper behavior.  The user is able to login when they provide valid credentials.  However, the session data is still never being written to the database.  Any idea why? </p>