...

View Full Version : SessionStart function failure



MattyUK
02-25-2010, 07:30 PM
Hi

I'm stuck on why a session function won't work.

I have two test pages that should create and then print a session variable between the two.

page1.php


function sessionStart()
{
if(headers_sent()&&(session_id()==''))
{
return false;//can't use this function if you have sent headers already. Don't want to use existing session
}//from: if(headers_sent()&&(session_id()==''))

//Force cookies and the params we want
ini_set('session.use_cookies',true);
ini_set('session.use_only_cookies',true);
ini_set('session.use_trans_sid',false);//no url sids
ini_set('url_rewriter.tags','');//Don't rewrite tags for the sid
ini_set('session.cookie_lifetime',1800);//1800=30mins
ini_set('session.cookie_domain','.mydomain.com');
ini_set('session.cookie_secure',true);
ini_set('session.cookie_path','/');
ini_set('session.cookie_httponly',true);
//Garbage collect old sessions now please
ini_set("session.gc_maxlifetime", 1800);
ini_set("session.gc_divisor", "1");
ini_set("session.gc_probability", "1");

//Fire it up
session_start();//Can't simply test for true since may be less than PHP 5.3 (currently 5.2.9)

//should we check that the cookies params are the same as our ini_set? if session_start reuses a session started with different params will the new values overwrite the old?
if(session_id()!='')
{
session_regenerate_id();//may have reused old session so lets get a new SID for giggles
return true;//All is good (we hope)
}//from: if(session_id()!='')
else
{
//Something went wrong. run away
return false;
}//from: else
//done. bye
}//from: function sessionStart()

if(!sessionStart()){exit;}

//remove this next line for page2.php
$_SESSION['val']='my value';

echo '<pre>';print_r(session_get_cookie_params());echo '</pre><br/>';
echo '<pre>'.session_id().'</pre><br/>';
echo '<pre>';print_r($_SESSION);echo '</pre><br/>';


Then on page2.php it is identical source code except $_SESSION['val']='my value'; is removed.

The 'my value' string is printed out on the first page, but not the second. A different session_id is presented but I do want it regenerated each request. session_regenerate_id should collect the existing session variables and transpose them onto the new session right?

Can anyone help me figure out where am I going wrong please?

Using php 5.2.9, and I've forced https via .htaccess and BASIC authentication is currently used.


Matty

Dormilich
02-25-2010, 08:27 PM
strange indeed, on first trial had the same issue, after temporarely commenting out the ini settings, it worked.

MattyUK
02-25-2010, 08:54 PM
Humm, I found a work around. What I can't explain is why it is necessary. Perhaps a bug.

I now grab the session variables into a variable then import them into the new session.


function sessionStart()
{
if(headers_sent()&&(session_id()==''))
{
return false;//can't use this function if you have sent headers already. Don't want to use existing session
}//from: if(headers_sent()&&(session_id()==''))

//Force cookies and the params we want
ini_set('session.use_cookies',true);
ini_set('session.use_only_cookies',true);
ini_set('session.use_trans_sid',false);//no url sids
ini_set('url_rewriter.tags','');//Don't rewrite tags for the sid
ini_set('session.cookie_lifetime',1800);//1800=30mins
ini_set('session.cookie_domain','.realworldfocus.com');
ini_set('session.cookie_secure',true);
ini_set('session.cookie_path','/');
ini_set('session.cookie_httponly',true);
//Garbage collect old sessions now please
ini_set("session.gc_maxlifetime", 1800);
ini_set("session.gc_divisor", "1");
ini_set("session.gc_probability", "1");

//Fire it up
session_start();//Can't simply test for true since may be less than PHP 5.3 (currently 5.2.9)

//should we check that the cookies params are the same as our ini_set? if session_start reuses a session started with different params will the new values overwrite the old?
if(session_id()!='')
{
//this next line doesn't work as expected it doesn't propagate session variables as the manual states it should.
//session_regenerate_id();//may have reused old session so lets get a new SID for giggles

//workaround start
//Grab current session vars
$aSession=$_SESSION;
//generate new session,
session_regenerate_id(false);//may have reused old session so lets get a new SID for giggles
//Grab new SID
$sNewSID=session_id();
//close both
session_write_close();
//import grabbed variables
$_SESSION=$aSession;
unset($aSession);//habit. no longer needed
unset($sNewSID);//habit. no longer needed
//workaround end

return true;//All is good (we hope)
}//from: if(session_id()!='')
else
{
//Something went wrong. run away
return false;
}//from: else
//done. bye
}//from: function sessionStart()

Comments very welcome.

I may start nailing down which ini_set line causes it. Perhaps the garbage collection?
If I comment out the session_regenerate_id line and don't include the workaround then it works fine with the SID.

Matt

Dormilich
02-26-2010, 05:07 AM
what I use for session handling

MattyUK
02-27-2010, 07:47 PM
Dormilich, thank you. Much appreciated and always helpful to see other examples.

I've posted the functions I completed below. I'd be curious to see if there are any glaring problems.

I may start a new thread with some related questions on cookie injection and deleting cookies that you may not have set.

I discovered the problems with the function originally were a second cookie set with parameters different that what was set with the ini_set functions.

Essentially I had one cookie set as httponly, secure and expires in 30mins and another set as a session cookie, insecure. So it seemed prudent to devise a destroy all cookies script to clean up before setting the cookie we want or to cycle through the possible setcookie parameters to ensure the largest possible capture of potential cookie sets.

I haven't given the sessionEnd function much thought yet and just threw it together. Since it isn't working as expected I think it may be flawed on a conceptual approach.

session.php (the functions)

function sessionStart()
{
if(headers_sent())
{
return false;//can't use this function if you have sent headers already. Don't want to use existing session
}//from: if(headers_sent())

//Force cookies and the params we want
ini_set('session.use_cookies',true);
ini_set('session.use_only_cookies',true);
ini_set('session.use_trans_sid',false);//no url sids
ini_set('url_rewriter.tags','');//Don't rewrite tags for the sid
ini_set('session.cookie_lifetime',0);//1800=30mins,0=session cookie
ini_set('session.cookie_domain','.realworldfocus.com');
ini_set('session.cookie_secure',true);
ini_set('session.cookie_path','/');
ini_set('session.cookie_httponly',true);
//Garbage collect old sessions now please
ini_set('session.gc_maxlifetime',1800);
ini_set('session.gc_divisor','1');
ini_set('session.gc_probability','1');

//Fire it up.
session_start();//Can't simply test for true since may be less than PHP 5.3 (currently 5.2.9)

//should we check that the cookies params are the same as our ini_set? if session_start reuses a session started with different params will the new values overwrite the old?
if(session_id()!='')
{
//Remember this will take care of the session (server side) but not the cookie presented by the client
session_regenerate_id(true);//may have reused old session so lets get a new SID for giggles

return true;//All is good (we hope)
}//from: if(session_id()!='')
else
{
//Something went wrong. run away
return false;
}//from: else
//done. bye
}//from: function sessionStart()


function sessionEnd()
{
if(headers_sent())
{
return false;//can't use this function if you have sent headers already.
}//from: if(headers_sent())
if(session_id()!='')//should I test for $_COOKIE values instead?
{
//In order to kill it carefully we have to access it first.
//This will reuse existing one we can then kill, or create new we can then kill
session_start();

//unset session vars
$_SESSION=array();

//kill the cookie monster
$aCI=session_get_cookie_params();//Array Cookie Info

//setcookie(session_name(),'',time()-42000,$aCI['path'],$aCI['domain'],$aCI['secure'],$aCI['httponly']);
//whilst the above line would be good normally, what if cookie injection set one up with additional/different params?
/*
setcookie(session_name(),'',time()-42000, $aCI['path'],$aCI['domain'],$aCI['secure'],$aCI['httponly']);
setcookie(session_name(),'',time()-42000, $aCI['path'],$aCI['domain'],$aCI['secure']);
setcookie(session_name(),'',time()-42000, $aCI['path'], $aCI['domain']);
setcookie(session_name(),'', time()-42000,$aCI['path']);
*/
if((empty($aCI['domain']))&&(empty($aCI['secure'])))
{
setcookie(session_name(),'', time()-42000,$aCI['path']);
}
elseif(empty($aCI['secure']))
{
setcookie(session_name(),'',time()-42000, $aCI['path'], $aCI['domain']);
}
elseif(empty($aCI['httponly']))
{
setcookie(session_name(),'',time()-42000, $aCI['path'],$aCI['domain'],$aCI['secure']);
}
else
{
setcookie(session_name(),'',time()-42000, $aCI['path'],$aCI['domain'],$aCI['secure'],$aCI['httponly']);
}
unset($aCI);//habit. var no longer needed
//Kill the session.
session_destroy();
//Kill the cookie global for now
unset($_COOKIE[session_name()]);
//couldn't I just use unset($_COOKIE); and catch ALL potentially present cookies (like injected ones)?
//unset($_COOKIE);

return true;
}//from: if(session_id()!='')
else
{
return false;//no session apparently set, so lets move on
}//from: else
//Done. bye
}//from: function sessionEnd()


page1.php (kill existing sessions if any and set session values)


include './session.php';

sessionEnd();
if(!sessionStart()){exit('sessionStart false');}

$_SESSION['val']='my value';

echo '<pre>CookieParams: ';print_r(session_get_cookie_params());echo '</pre><br/>';
echo '<pre>SID: <br/>'.session_id().'</pre><br/>';
echo '<pre>Cookies: <br/>';print_r($_COOKIE);echo '</pre><br/>';
echo '<pre>Session Values:<br/>';print_r($_SESSION);echo '</pre><br/>';


page2.php (read existing session sessions and values OR test the discarding and killing of existing sessions [doesn't work well])

include_once './session.php';
//comment out next code line if you want to propagate and read the values set in page1.php //seems to work
//uncomment next code line to kill previous sessions and discard data set in page1.php //doesn't seem to work
sessionEnd();
if(!sessionStart()){exit;}

echo '<pre>CookieParams: ';print_r(session_get_cookie_params());echo '</pre><br/>';
echo '<pre>SID: <br/>'.session_name().' '.session_id().'</pre><br/>';
echo '<pre>Cookies: <br/>';print_r($_COOKIE);echo '</pre><br/>';
echo '<pre>Session Values:<br/>';print_r($_SESSION);echo '</pre><br/>';


I'm going to take a closer look at your class once I've got these functions polished to satisfaction. Something along the lines of "I've started so I'll finish" mentality.

Any help with sessionEnd would be appreciated. May shorten some reading.

Matty

MattyUK
02-28-2010, 04:02 PM
Ok for whatever reason in sessionEnd I had included:

if(session_id()!='')//should I test for $_COOKIE values instead?
{
before I had called session_start. Doh. So removing this is the answer.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum