views:

5396

answers:

7

I'm using PHP 4.3.9, Apache/2.0.52

I'm trying to get a login system working that registers DB values in a session where they're available once logged in. I'm losing the session variables once I'm redirected.

I'm using the following code to print the session ID/values on my login form page and the redirected page:

echo '<font color="red">session id:</font> ' . session_id() . '<br>';
echo '<font color="red">session first name:</font> ' . $_SESSION['first_name'] . '<br>';
echo '<font color="red">session user id:</font> ' . $_SESSION['user_id'] . '<br>';
echo '<font color="red">session user level:</font> ' . $_SESSION['user_level'] . '<br><br>';

This is what's printed in my browser from my login page (I just comment out the header redirect to the logged in page). This is the correct info coming from my DB as well, so all is fine at this point.

session id: 1ce7ca8e7102b6fa4cf5b61722aecfbc
session first name: elvis
session user id: 2
session user level: 1

This is what's printed on my redirected/logged in page (when I uncomment the header/redirect). Session ID is the same, but I get no values for the individual session variables.

session id: 1ce7ca8e7102b6fa4cf5b61722aecfbc
session first name:
session user id:
session user level:

I get the following errors:

Undefined index: first_name
Undefined index: user_id
Undefined index: user_level

I have a global header.php file which my loggedIN.php does NOT call, though loggedOUT.php does - to toast the session):

header.php

<?php
ob_start();
session_start();

//if NOT on loggedout.php, check for cookie. if exists, they haven't explicity logged out so take user to loggedin.php
if (!strpos($_SERVER['PHP_SELF'], 'loggedout.php')) {
    /*if (isset($_COOKIE['access'])) {
     header('Location: www.mydomain.com/loggedin.php');
    }*/
} else {
    //if on loggedout.php delete cookie
    //setcookie('access', '', time()-3600);

    //destroy session
    $_SESSION = array();
    session_destroy();
    setcookie(session_name(), '', time()-3600);
}

//defines constants and sets up custom error handler
require_once('config.php');

?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;

some page layout stuff

Login portion is eventually called via include

footer stuff

My loggedIN.php does nothing but start the session

<?php
session_start();
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;

The logic of my login script, the key part being I'm fetching the DB results right into $_SESSION (about half way down):

if (isset($_POST['login'])) {
  //access db
  require_once(MYSQL);

  //initialize an errors array for non-filled out form fields
  $errors = array();

  //setup $_POST aliases, clean for db and trim any whitespace
  $email = mysql_real_escape_string(trim($_POST['email']), $dbc);
  $pass = mysql_real_escape_string(trim($_POST['pass']), $dbc);

  if (empty($email)) {
   $errors[] = 'Please enter your e-mail address.';
  }

  if (empty($pass)) {
   $errors[] = 'Please enter your password.';
  }

  //if all fields filled out and everything is OK
  if (empty($errors)) {
   //check db for a match
   $query = "SELECT user_id, first_name, user_level 
     FROM the rest of my sql here, blah blah blah";

   $result = @mysql_query($query, $dbc) 
    OR trigger_error("Query: $query\n<br />MySQL Error: " . mysql_error($dbc));

   if (@mysql_num_rows($result) == 1) { //a match was made, OK to login

    //register the retrieved values into $_SESSION
    $_SESSION = mysql_fetch_array($result);
    mysql_free_result($result);
    mysql_close($dbc);
    /*    
    setcookie('access'); //if "remember me" not checked, session cookie, expires when browser closes
          //in FF you must close the tab before quitting/relaunching, otherwise cookie persists

    //"remember me" checked?
    if(isset($_POST['remember'])){ //expire in 1 hour (3600 = 60 seconds * 60 minutes)
     setcookie('access', md5(uniqid(rand())), time()+60); //EXPIRES IN ONE MINUTE FOR TESTING
    }
    */

echo '<font color="red">cookie:</font> ' . print_r($_COOKIE) . '<br><br>';
echo '<font color="red">session id:</font> ' . session_id() . '<br>';
echo '<font color="red">session first name:</font> ' . $_SESSION['first_name'] . '<br>';
echo '<font color="red">session user id:</font> ' . $_SESSION['user_id'] . '<br>';
echo '<font color="red">session user level:</font> ' . $_SESSION['user_level'] . '<br><br>';

    ob_end_clean();
    session_write_close();

    $url = BASE_URL . 'loggedin_test2.php';
    header("Location: $url");
    exit();
   } else {
   //wrong username/password combo
   echo '<div id="errors"><span>Either the e-mail address or password entered is incorrect or you have not activated your account. Please try again.</span></div>';
   }

   //clear $_POST so the form isn't sticky
   $_POST = array();
  } else { 
  //report the errors
  echo '<div id="errors"><span>The following error(s) occurred:</span>';

   echo '<ul>';
   foreach($errors as $error) {
    echo "<li>$error</li>";
   }
   echo '</ul></div>';
  }

 } // end isset($_POST['login'])

if I comment out the header redirect on the login page, I can echo out the $_SESSION variables with the right info from the DB. Once redirected to the login page, however, they're gone/unset.

Anyone have any ideas? I've spent nearly all day on this and can't say I'm any closer to figuring it out.

BTW, I recently made 2 simple test pages, one started a session, set some variables on it, had a form submit which redirected to a second page which did nothing but read/output the session vars. It all seems to work fine, I'm just having issues with something I'm doing in my main app.

+2  A: 

Try doing a

session_regenerate_id(true);

before the

session_write_close();

Also. The best way IMO to do a login script is this:

Let the login logic be handled within the mainpage the user is trying to access.

  1. If the user is not authenticated, he is thrown back to the login page
  2. If the user is authenticated, he gets an $_SESSION["auth"] or something
  3. Then when the user is browsing the main page or other pages that need auth, they just check if the $_SESSION["auth"] is set.

Then you wont have the trouble of session not saving just before a redirect

Ólafur Waage
This is a great answer!
Masi
Thank you : )
Ólafur Waage
The logic of my login script is based on it at http://stackoverflow.com/questions/1270005/to-set-up-a-login-system-by-sessions-in-php
Masi
A: 

No difference, loggedIN.php still prints the session ID only. Also, the session_write_close() doesn't seem to matter. I didn't have it to begin with and I would only get the session ID printed.

Yeah, I think I'm probably going to end up re-writing this authentication a bit. I first set it up with just cookies for testing and a static username/pass. That all worked fine. Then moved on to authenticating from actual DB credentials and redirecting. That's not going so well, lol.

Just a quick fyi, to use the comments for chat like this, since what you posted isn't actually an answer :) But glad i helped a bit :)
Ólafur Waage
Yeah, I just figured out how the reply thing works here.
+3  A: 

I don't see a session_start() in your login script. If you aren't starting the session I don't think php will save any data you place in the $_SESSION array. Also to be safe I'd explicitly place variables into the $_SESSION array instead of just overwriting the whole thing with $_SESSION = mysql_fetch_array($result);.

Rob Booth
Hey, putting the DB values manually in the $_SESSION array looks like it did the trick. Thanks so much! Is it because I'm stuck using PHP 4.3.9 ?
4.3.9 is ancient.
jmucchiello
A: 

The login script is eventually included by the header.php for the session_start(). If I comment out the header redirect, I can output the session vars just fine. I'll try manually putting the DB values in the $_SESSION array...

<?php require "headerNEW.php"; ?>  **SESSION_START();**

some page stuff

<?php require "login.php"; ?>  **THE LOGIN FORM**

<?php require "footer.php"; ?>
Ok, I was confused by your comment "I have a global header.php file which my loggedIN.php does NOT call, though loggedOUT.php does - to toast the session):" I thought that ment your code below didn't use your header.
Rob Booth
A: 

THIS SEEMED TO DO THE TRICK - THANK YOU!!!!!!!!

Is this due to the older version of PHP (PHP 4.3.9) I'm unfortunately stuck with at the moment?

I'd explicitly place variables into the $_SESSION array instead of just overwriting the whole thing with $_SESSION = mysql_fetch_array($result);.

+1  A: 

I see now!

Correct me if I'm wrong, but it seems one needs a session_start() on EVERY php page that one wants to work with sessions on!

+2  A: 

+1 for session_start() having to be in every PHP script that uses session variables. That was my problem today, after the login script put variables in the session and redirected the session was empty. Putting a session_start on the page that got redirected to fixed it.

Kawika