By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,751 Members | 1,158 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,751 IT Pros & Developers. It's quick & easy.

session does not propagate after header("Location: page.php")

bilibytes
100+
P: 128
hi,

i am making a website with php OOP.
i have a class called session:
it has the attribues
-logged_in;
-user_name;
-user_ip;
-user_level;

and two methods
-__construct
-starter()
-check_logged_in()

ok
constructor calls:
session_start()
and sets:
-logged_in = check_session;

the starter, ... puts all the user information into $_SESSION array and then assigns that values to the user attributes: -user_name, -user_ip...

so when i call the object instance, constructor will determine if the user is logged in by calling -check_session which checks if:
$_SESSION[user_name] ... exist, if yes, it assigns its values to the attribues
and returns true, else returns false.

the point is that when i start the session by calling starter at one point of the script, and print_r($_SESSION) it will output all the user information which is normal.. this means the session has been correctly started.

BUT, when from the same part of the script, i redirect the user with header("location:page.php")
page.php will call session->logged_in and it will return false....

is there a reason for that?

thnak you

bilibytes
Sep 21 '08 #1
Share this Question
Share on Google+
5 Replies


Atli
Expert 5K+
P: 5,058
Hi.

Could we see the actual code?

Your explanation makes it sound like it should work, in theory, but we can't really know why it isn't working unless we can see the code.
Sep 21 '08 #2

bilibytes
100+
P: 128
here is the session.php class:

[PHP]class Session
{
const LEVEL_ADMIN = 1;
const LEVEL_S_USER = 2;
const LEVEL_G_USER = 8;
const LEVEL_GUEST = 9;

public $logged_in; //TRUE if user has given a good PHPSESSID and this SESSID comes from the same IP that athenticated
public $user_name;
public $user_IP;
public $user_level;
public $error;

function __construct(){
if(!isset($_SESSION))
{
session_start();
}
$this->logged_in = $this->check_session();
}

function starter($username, $level){//this method is called from session_auth
global $database, $calendar_auto_updater;

/**
* Session Start - sets a session cookie
*
*
* 1. First time user opens the page (there is no file in the server)
*
* -PHP generates a random value which is used to
* -give value to PHPSESSID: cookie that he sends to Client'sBrowser
* -Client's Browser keeps it for an undefined period of time
* -give name to a File in the Server
*
*
* 2. n>1 Time user opens the page (there is a file in the server)
*
* -Client's Browser Sends an HTTP Header with the PHPSESSID cookie
* -PHP gets PHPSESSID cookie value with session_start()
* -Looks for a file named like the value contained in the cookie (assumming he finds it)
* -Reads its content and creates an array $_SESSION containing the pairs key values
* -At the end of the script if there are $_SESSION[''] attributions:
* -Write into the server file
*/


session_regenerate_id();

$this->user_name = $_SESSION['user_name'] = $username;
$this->user_IP = $_SESSION['user_IP'] = $_SERVER['REMOTE_ADDR'];
$this->user_level = $_SESSION['user_level'] = $level;
if($calendar_auto_updater->auto() == true){
if($database->DB_add_active_user($this->user_name, $this->user_IP, $this->user_level, session_id()) == true){
/**
* we have to recall check session to set logged in = true because at object instace calling,
* the constructor checks logged in before starting a new session
* with $this->starter.
* this is: firts logged_in == false and once starter called logged_in should be true, but check_session is not called again.
* this is why logged_in has to be set to logged_in from starter method
*/
$this->logged_in = true;
return true;
}
else{
$this->error = "could not insert active user into db";
return false;
}
}
else{
print_r($calendar_auto_updater->error);
}

}

function check_session(){
global $database;

/**
* if the user has been authenticated, the script has sotred his name on session file
* so if the user gives a SESSID which refers to a file with no name on it, this mean
* it is a malicious user.
* if the user gives a SESSID which refers to a file with a name on it, check if the
* SESSID comes from the same IP the first user authenticated from.
*/

if(isset($_SESSION['user_name']) && isset($_SESSION['user_IP'])){//there is a value in file with key user_name
if($_SERVER['REMOTE_ADDR'] == $_SESSION['user_IP']){// if the client IP corresponds to the first (authenticated) client IP
/* Check if the user is logged in, if yes, store session variables, else log him totally out */
if($database->DB_check_active_user($this->user_name, $this->user_IP) == true){
$this->user_name = $_SESSION['user_name'];
$this->user_IP = $_SESSION['user_IP'];
$this->user_level = $_SESSION['user_level'];
return true;
}
else{
$this->unset_session();
return false;
}
}
else{//there is a fraud, report it to DB
$database->DB_report_fraud($_SESSION['user_name'], $_SERVER['REMOTE_ADDR']);
return false;
}
}
else{// the user is not authenticated
return false;
}
}

public function add_session_vars($obj ,$key, $value){
$_SESSION[$obj][$key] = $value;
if($_SESSION[$obj][$key] == true){
return true;
}
else{
return false;
}
}

function unset_session(){
global $database;

// Unset all of the session variables.
$_SESSION = array();

// If it's desired to kill the session, also delete the session cookie.
// Note: This will destroy the session, and not just the session data!
if (isset($_COOKIE['PHPSESSID'])) {
setcookie('PHPSESSID', '', time()-42000, '/');
}

// Finally, destroy the session.
session_destroy();

if($database->DB_set_unactive_user($this->user_name, $this->user_IP)){
return true;
}
else{
print_r($database->error);
}
}

}
?>[/PHP]

then here is the session_auth.php class, it is used to check the posted user credentials consistency:

[PHP]class Session_auth extends Session
{
const MAX_PASS_ERR = 3; //number of times a user is allowed to fail submiting password

private $secured = "jo2lDly5ju_m66FDperIs%";
public $errors = false;
private $DB_response; //stores the result of DB class query
public $pre_user; //username with stripslashes for DB checking
private $pre_pass; //password with stripslashes + md5 for DB checking
public $pre_mail;

/* Basic form submitted data checking */
function login($sub_user, $sub_pass){
global $database, $session, $account_manager, $pre_session; //+$mail

$this->pre_user = $sub_user;

/* -USERNAME- */
/* Check it the username is long enough getting rid of spaces */
if(!$sub_user || strlen($sub_user) < 8){
$this->errors['sub_user']['char'] = "Need Username, minimum length is 8";
}
/* Check if username is not alphanumeric */
else if(!eregi("^([0-9a-z])*$", $sub_user)){
$this->errors['sub_user']['char'] = "Username not alphanumeric";
}
/* Store sub_user on a momentanious var $pre_user */
else{
$this->errors['sub_user'] == false; //no errors
}
/* -PASSWORD- */
/* Check it the password is long enough getting rid of spaces */
if(!$sub_pass || strlen($sub_pass) < 8){
$this->errors['sub_pass']['char'] = "Need Password, minimum length is 8";
}
/* Store sub_pass on a momentanious var $pre_pass with md5 */
else{
$this->pre_pass = md5($sub_pass);
$this->errors['sub_pass'] == false; //no errors
}

/* CHECK AGAINST DB and do... */
if($this->errors['sub_user']['char'] == false && $this->errors['sub_pass']['char'] == false){//if no character errors

$this->DB_response = $database->DB_login_credentials($this->pre_user, $this->pre_pass);

/* User and Pass match in DB */
if($this->DB_response == true){
unset($this->errors); // delete error content for next try
if($database->DB_check_unactive_user($this->pre_user, "all") == true){//check if the user is not logged in from elswhere

if($database->DB_isnot_quarantine_user($this->pre_user) == true){//check if the user is in quarantine
/* The user seems has the rights to log in */
if($session->starter($this->pre_user, $database->response_level) == true){
return true;
}
else{
$this->errors['general']['auth'] = "Sorry, the system was unable to log you in, there was a Server error";
return false;
}
}
else{
$session->starter($this->pre_user, 8); //start a session with reduced powers, to make availible user_name to quarantine to resend a mail
$this->errors['general']['auth'] = "You were put in quarantine at last login attempt, please check your mail box, an e-mail should have been sent. Click here to be sent another one. <a href=quarantine.php?mail=resend>Resend em@il</a>";
return false;
//$database->error['log']['user'] is the real error
}
}
else{ //the user has logged in from a different ip
//as the user has given the right credentials, but he has to logout before relogging in...
//so create a pre session that will only allow him to loggin after having done what we asked him
$pre_session->pre_starter($this->pre_user, $database->response_level);
$this->errors['session_auth'] = $database->error['log']['user'];
$database->DB_report_fraud($this->pre_user, $_SERVER['REMOTE_ADDR']);
return false;
}
}
/* DB returns Error */
else{
if($database->error['log']['user'] == true){//user does not exist in db
$this->errors['sub_user']['DB'] = $database->error['log']['user'] ;
return false;
}
else if($database->error['log']['pass'] == true){//the client has submited wrong password
if($database->DB_isnot_quarantine_user($this->pre_user)){//the user is not in quarantine, so lets see how many tries he has left and put him in quarantine if necessary
if($database->DB_report_wrong_pass($this->pre_user, $this->pre_pass.$sub_pass, $_SERVER['REMOTE_ADDR']) == true){
//calculate the number of tries left
$max_tries = Session_auth::MAX_PASS_ERR;
$actual_tries = $database->response;
$left_tries = $max_tries - $actual_tries;
if($left_tries < 1){//the user has reached his maximum attempts Put him in quarantine with a brand new generated md5 password to validate via url in mail
//first get user e-mail
$database->DB_get_mail($this->pre_user);//stores mail into a variable of database class
if($account_manager->credentials_refactor($this->pre_user, $database->mail, $this->secured) == true){ //create a new password for the account
/**
* $account_manager will create a new password, and will insert the user_name user_ip and user_new_pass into table quarantine
* and will send the user a url with the password
* when quarantine.php recives the right password, it calls again account manager to
* delete the user from quarantine table and asks him for a new password
* when POST new password is true, it calls again account manager to update the data into users table
*/
$this->errors['general']['auth'] = "You reached the maximum wrong password submitting attempts, an e-mail has been sent to your box with a link and all the instructions to follow up.";//store error, auth will send this to client_side
return false;
}
else{
$this->errors['internal']['account_manager'] = "Problem while creating new credentials for account, ".$account_manager->error;
return false;
}
}
else{
$this->errors['sub_pass']['auth'] = "You entered a wrong password, ".$left_tries." tries left.";// make a system where
return false;
}
}
else{
$this->errors['internal']['mysql'] = $database->error['req']['mysql'];
return false;
}
}
else{//the user is already in quarantine and has submited wrong credentials, take his ip and bann him
$this->errors['general']['auth'] = "You were put in quarantine at last login attempt, please check your mail box, an e-mail should have been sent.";
return false;
}
}
else{
$this->errors['internal']['mysql'] = $database->error['req']['mysql'];
return false;
}
}
}
else{//if character errors
return false;
}
}
}
?>
[/PHP]

then, here is the lowest page auth.php, which receives all data and transmits it to session_auth :

[PHP]<?php
include_once("includings/inc.php");

/**
* User wants to login: submitted SUPERGLOBALS
*/
if(isset($_POST['user_name']) || isset($_POST['user_pass'])){

if($session->logged_in != true){
/*Store values*/
$posted_u_n = substr(trim(htmlentities($_POST['user_name'])), 0, 20);
$posted_u_n = preg_replace('/[^\w\.\-\& ]/', '', $posted_u_n);
$posted_u_p = substr(trim(htmlentities($_POST['user_pass'])), 0, 20);
$posted_u_p = preg_replace('/[^\w\.\-\&]/', '', $posted_u_p);

/*Check login succeed*/
if ($session_auth->login($posted_u_n, $posted_u_p) == true){
//redirect to logged in section
header("Location: calendar.php");
}
else{//login failed or the user logged in but is still in quarantine
$client_side->HTML_login_form($session->user_name, $session_auth->errors);
}
}
else{
$error['logout']['can'] = 'log yourself out';
$client_side->HTML_login_form($session->user_name, $error);//can logout
}
}
/**
* User wants to logout: submited SUBERGLOBALS
*/
else if($_GET['logout'] == 'true'){
/*Check if logged in*/
if($session->logged_in == true){
/*Log him out*/
if($session->unset_session() == true){
//logout succeed
$error['logout'] = 'logged out';
$client_side->HTML_login_form("Guest", $error);//message: you have logout + login form
}
else{
//unable to log you out
$error['logout'] = 'could not logout';
$client_side->HTML_login_form($session->user_name, $error); //message: unable to logout
}
}
else{
if($pre_session->pre_logged_in == true){ // the user was logged in from another ip, and wants to logout and relogin from this ip. Already gave good credentials
/* Set all the records on whose is said: active = 1 to 0 */
/* Now when the user, that had logged in from the other ip checks if he is active, he wond find a record with IP active = 1 */
if($database->DB_set_unactive_user($pre_session->pre_user_name, "all") == true){
/* Start a normal session which gives him his normal powers */
if($session->starter($pre_session->pre_user_name, $pre_session->pre_user_level) == true){
if($session->logged_in == true){//------------------AT THIS POINT SESSION IS STARTED OK
header("Location: page.php");//---------------------HERE IS THE PROBLEM

}
else{
print "not logged in";
}
}
else{
//unable to log you out
$error['login'] = 'could not login';
$client_side->HTML_login_form($session->user_name, $error);
}
}
else{
//unable to log you out
$error['logout'] = 'could not logout';
$client_side->HTML_login_form($session->user_name, $error); //message: unable to logout
}
}
else{
//you are not logged in
$error['logout']['can'] = 'not logged in';
$client_side->HTML_login_form("Guest", $error); //message: not logged in cant logout...
}
}
}
/**
* User can login: requested Blank page
*/
else{//user requests this page from elsewhere than a form

//show the first login fosrm
if($session->logged_in == false){
$error['first'] = '1';
$client_side->HTML_login_form('Guest',$error);//can login_form + register_link
}
else{
$error['logout']['can'] = 'log yourself out';
$client_side->HTML_login_form($session->user_name, $error);//can logout
}

}
?>[/PHP]

when the parser goes to where i wrote ----------HERE IS THE PROBLEM (above), the session is started ok, but when it redirects to the script: page.php, it calls $session->logged_in and it returns false, the user is no longer logged in
here is the code of page.php:

[PHP]
class page_class
{

private $data_array = array();
private $formatted_array = array();
public $error = false;

public function __construct(){
global $session, $client_side, $database;


/* Check Session - Only make calendar actions if user logged in */
if($session->logged_in == true){
print "you are logged in";
}
}
[/PHP]

all these files are correctly included in inc.php which is itself included in auth.php

from the client side, it looks as if the script regenerated a new PHPSESSID when going to the other script and that should be the reason why $session->logged_in returns false...
but i don't know where i tell PHP to create a new session id at each time a new page is sent...
with firefox i can see that the request header sends PHPSESSID: XXX and the response header returns another PHPSESSID: YYY
i cant understand why the session is lost.

from the server side, i can see in /temp that all the sessions are still there and that they were not removed by session.max_liftime

do you see a reason why php would generate a new session id at each time?

Firstly i thought that this might be because of the session_regenerate_id() when i start the session, but this is done only once... when $session->starter() is called. but when $session::__construct calls $session->check_session() to determine whether logged_in is true or not it never regenerates_id.

Please if you have any suggestion let me know

Thankyou very much for your time

bilibytes
Sep 21 '08 #3

P: 9
Hi,
Even I am having similar problem.

In login page i had set session variables. But after page is redirected throgh header() to another page, sessions doesnt work any more.
isset($_SESSION['username']) is returning false.

Please help me.

Thankyou.
Nov 14 '08 #4

P: 9
This is the first website I am developing on my machine. Do I have make any changes to php.ini file?
Nov 14 '08 #5

Markus
Expert 5K+
P: 6,050
This is the first website I am developing on my machine. Do I have make any changes to php.ini file?
Don't post your question multiple times. Start your own thread for your own questions.

Moderator.
Nov 14 '08 #6

Post your reply

Sign in to post your reply or Sign up for a free account.