PDA

View Full Version : PHP Sessions & IRMs


hobbes
07-18-2005, 12:44 PM
I need to pass a PHP session from a script running under an IRM to a script running under the IRM's primary account so an SSL connection under the primary account can be established.

The hand off from the IRM to the primary is through a location header, where I've inserted the session id:header('Location: ' . $url . '?' . session_name() . '=' . session_id());
Unfortunately the session doesn't appear to carry over.

Anything special about the FQ config that would prevent this? Is the session cache not shared between an IRM and its primary account?

Thx for any insight.

hobbes
07-18-2005, 12:55 PM
Looks like when transfered to the primary acct a new session id was being assigned. Was able to get around it by checking for one in $_GET and setting session_id with it.

kitchin
07-18-2005, 01:22 PM
... that's good to know!...

What I was writing:

I've had similar problems. It will probably work if you turn off cookies. Either in your browser, or from the server:

.htaccess:
php_flag session.use_cookies off
php_flag session.use_trans_sid on

The second line would be needed on an https:// address, because by default trans_sid is OFF on the secure server at FQ, and you need some way to carry the session.

That is the one difference I've found between the normal server and the (shared) secure server at FQ: session.use_trans_sid is ON, which is PHP default, on the normal server, and changed to OFF on the secure server.

If PHP thinks it can use cookies, because your browser allows them, then apparently it will try to use cookies, even if you send it a session id (trans_sid) in the URL. So it will just ignore the URL session id and start a new session. That is how it seemed to me.

Here is a script to check the server variables. I'm working on a more complete one.


<pre>
<?php
printf("session.use_trans_sid [%s]\n", ini_get('session.use_trans_sid'));
printf("session.use_cookies [%s]\n", ini_get('session.use_cookies'));
printf("session.use_only_cookies [%s]\n", ini_get('session.use_only_cookies'));
printf("session_save_path [%s]\n", session_save_path());
printf("register_globals [%s]\n", ini_get('register_globals'));
?>
</pre>

It's the first one only that changes between normal/secure, at FQ. Of course, there is a reason: trans_sid is more subject to session hijacking, say, on a public terminal.

kitchin
07-18-2005, 02:40 PM
Actually, trans_sid has PHP default OFF according to the PHP manual. At FQ it is ON for http:// and OFF for https://

Here is a terrible quick comparison script to check which values at FQ are not default.

<b>Comparison of server settings to the table at
<a href="http://us3.php.net/manual/en/ref.session.php">
us3.php.net/manual/en/ref.session.php</a>:</b><br>

<?php
// Paste the HTML of the current manual table into the load function below.
// And hope it still parses!

$st= load();
$st= preg_replace('/\s+$/m', '', $st);
if (preg_match('/<\/TBODY\s*><\/TABLE\s*>\s*$/', $st, $m)) {
$foot= $m[0];
$st= substr($st, 0, -strlen($m[0]));
} else {
printf("ERROR, parse 1 [...%s]", substr($st,0,-200));
exit;
}

$lns= array();
while (preg_match('/<TR\s*><TD\s*>(.*?)<\/TD\s*><TD\s*>(.*?)<\/TD\s*><TD\s*>(.*?)<\/TD\s*><TD\s*>(.*?)<\/TD\s*><\/TR\s*>$/', $st, $m)) {
$lns[]= array_slice($m, 1);
$st= substr($st, 0, -strlen($m[0]));
}

printf("
Found %d table rows......<br>", count($lns));

if (preg_match('/^\s*<TABLE.*<TBODY\s*>$/s', $st, $m)) {
$head= $st;
} else {
printf("ERROR, parse 2 [$st]");
exit;
}

print $head;
foreach (array_reverse($lns) as $ln) {
$val= '"' . ini_get($ln[0]) . '"';
$diff= $ln[1] != $val;
array_push($ln, $diff ? 'DIFF' : '-');
array_push($ln, $val);
if ($diff) {
for ($i=0; $i<count($ln); $i++) {
$ln[$i]= "<b>$ln[$i]</b>";
}
}
for ($i=0; $i<count($ln); $i++) {
$ln[$i]= "
<td>$ln[$i]</td>";
}

print "
<tr>" . implode('', $ln) . "</tr>";
}
print $foot;



/////////////////////
function load() {
// copy the HTML source of "Table 1. Session configuration options" of
// http://us3.php.net/manual/en/ref.session.php
// here:

print "PHP Manual table as of 2005/07/18.<br>";

return '<TABLE
BORDER="1"
CLASS="CALSTABLE"
><COL><COL><COL><COL><THEAD
><TR
><TH
>Name</TH
><TH
>Default</TH
><TH
>Changeable</TH
><TH
>Changelog</TH
></TR
></THEAD
><TBODY
><TR
><TD
>session.save_path</TD
><TD
>""</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.name</TD
><TD
>"PHPSESSID"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.save_handler</TD
><TD
>"files"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.auto_start</TD
><TD
>"0"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.gc_probability</TD
><TD
>"1"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.gc_divisor</TD
><TD
>"100"</TD
><TD
>PHP_INI_ALL</TD
><TD
>Available since PHP 4.3.2.</TD
></TR
><TR
><TD
>session.gc_maxlifetime</TD
><TD
>"1440"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.serialize_handler</TD
><TD
>"php"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.cookie_lifetime</TD
><TD
>"0"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.cookie_path</TD
><TD
>"/"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.cookie_domain</TD
><TD
>""</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.cookie_secure</TD
><TD
>""</TD
><TD
>PHP_INI_ALL</TD
><TD
>Available since PHP 4.0.4.</TD
></TR
><TR
><TD
>session.use_cookies</TD
><TD
>"1"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.use_only_cookies</TD
><TD
>"0"</TD
><TD
>PHP_INI_ALL</TD
><TD
>Available since PHP 4.3.0.</TD
></TR
><TR
><TD
>session.referer_check</TD
><TD
>""</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.entropy_file</TD
><TD
>""</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.entropy_length</TD
><TD
>"0"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.cache_limiter</TD
><TD
>"nocache"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.cache_expire</TD
><TD
>"180"</TD
><TD
>PHP_INI_ALL</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
>session.use_trans_sid</TD
><TD
>"0"</TD
><TD
>PHP_INI_ALL</TD
><TD
>PHP_INI_ALL in PHP <= 4.2.3. PHP_INI_PERDIR in PHP < 5. Available since PHP 4.0.3.</TD
></TR
><TR
><TD
>session.bug_compat_42</TD
><TD
>"1"</TD
><TD
>PHP_INI_ALL</TD
><TD
>Available since PHP 4.3.0.</TD
></TR
><TR
><TD
>session.bug_compat_warn</TD
><TD
>"1"</TD
><TD
>PHP_INI_ALL</TD
><TD
>Available since PHP 4.3.0.</TD
></TR
><TR
><TD
>session.hash_function</TD
><TD
>"0"</TD
><TD
>PHP_INI_ALL</TD
><TD
>Available since PHP 5.0.0.</TD
></TR
><TR
><TD
>session.hash_bits_per_character</TD
><TD
>"4"</TD
><TD
>PHP_INI_ALL</TD
><TD
>Available since PHP 5.0.0.</TD
></TR
><TR
><TD
>url_rewriter.tags</TD
><TD
>"a=href,area=href,frame=src,form=,fieldset="</TD
><TD
>PHP_INI_ALL</TD
><TD
>Available since PHP 4.0.4.</TD
></TR
></TBODY
></TABLE
>';

}
?>


:)

kitchin
08-11-2005, 12:06 AM
Well, this sure is easier:

<pre>
<?php
print_r(ini_get_all('session'));
?>
</pre>

It compares default values to local values.

Personally, I think session.gc_maxlifetime=1440 is a bit perverse, since it means a session may be destroyed after 24 minutes of inactivity. I'd rather sessions stay alive as long as the cookie does, which due to session.cookie_lifetime=0, is as long as the browser is open.

On a high-traffic site, the session garbage would build up with a high value for gc_maxlifetime. (The server has no way of knowing if the browser has closed, so gc_maxlifetime must be finite.) But otherwise 24 minutes seems way too low. I find myself losing the session while debugging. Or thinking about debugging... :)

kitchin
08-11-2005, 12:24 AM
<?php
ini_set('session.gc_maxlifetime', 2880);
session_start();
?>

Seems to be effective. The .htaccess way would be

php_value session.gc_maxlifetime 2880

hobbes
08-11-2005, 08:34 AM
FQ - can you confirm the 24 minute lifetime for browser-session cookies? If that's the value, would you consider changing it to 60 minutes?

kitchin
08-11-2005, 04:16 PM
It's not the cookie lifetime, it's the session garbage collection lifetime. If a session file, by default located in

/big/dom/xACCOUNTNAMEi/.sys_opr_dir/php_sessions,

has not been accessed in 24 minutes then it may be deleted. AFAIK, the garbage collector has a built-in randomness, and also only starts up when another php session gets going. Anytime after 24 minutes, an inactive session may be deleted. Changing the lifetime might be a problem on some shared servers, at least according to comments I read at php.net, but FQ keeps each account's sessions in a separate directory, above.

Feel free to bump if I interfered with your geting a response.... ;)

hobbes
08-11-2005, 04:55 PM
Oops, guess I should have read your post more closely. Regardless, 24 minutes is still too short given the GC algorithm's semi-randomness. I believe 1 hour is a much more appropriate minimum timeframe; though for some ecommerce sites it should probably be higher.

FQ?

Terra
08-11-2005, 06:50 PM
Regardless, 24 minutes is still too short given the GC algorithm's semi-randomness. I believe 1 hour is a much more appropriate minimum timeframe; though for some ecommerce sites it should probably be higher.
For things like this, I tend to be conservative and retain the stock default value...

I am not sure that increasing it for everyone is the right thing to do, since it is more often the case that designers will develop using the default values and adjust only if/when it is required... So far, there has been no demand to adjust the GC values, at least till now...

At this point, I'm on the fence about tweaking the GC values because I am not 100% positive it is the right or expected thing to do...

For now, if you want it tweaked, then either do it within your PHP scripts or add the override directive to your .htaccess file...

I guess the real question at this point, is why did the PHP developers choose '1440' as that value? What was their motivation, and why has it not changed through multiple major updates of the PHP engine...

--
Terra
--does not like changing default values unless there is a clear cut and defined case for doing so--
FutureQuest