Solved

disappearing session cookie with IP based address

Posted on 2006-07-09
15
335 Views
Last Modified: 2012-08-13
Running PHP 4.3.x

I have a get_host() function that returns the host name to use when setting cookies. Recently I wanted to modify it to handle IP based addresses and encountered some problems. I think the sample scripts below illustrate the problem pretty well. If you run the scripts with domain based addressing (i.e. "http://www.yourdomain.com/test1.php"), then everything works fine. If you run the scripts with IP based addressing (i.e. "http://12.34.56.78/test1.php") and click the "again with ip mode?" link, the session cookie is unavailable to test2.php. Why? How to fix?

This is taken from a login page that needs to authorize a user and redirect them to a restricted area.

file 1: "test1.php"
--------------------------
<?php

/*
start with a routine to kill existing session and start session over (this
is from a login page). if $_GET['mode'] is not set to "ip" when running with
an IP based address, then get_host() returns a truncated host name (i.e. ".12.34"),
which I'm pretty sure means the browser won't accept the setcookie() call.

If $_GET['mode'] is set to "ip" when running with
an IP based address, then full IP is returned by get_host, and setcookie()
call should work, with browser accepting cookie.
*/
if (!session_id())  session_start();
foreach ($_SESSION as $key => $value)  $_SESSION[$key] = '';
$host = get_host();
setcookie(session_name(),'',time()-86400,"/", $host, 0);
session_destroy();

session_start();

$msg = "host used='$host'<br />";
$msg .= "session_id on test1 was '".session_id()."'";

$redirect = 'http://'.$_SERVER['HTTP_HOST'].substr(dirname($_SERVER['SCRIPT_NAME']), 1)."/test2.php?msg=".urlencode($msg);

header('Location: '.$redirect);

function get_host()            ## $host used for setting cookies
{
      preg_match('/^(([A-Z0-9][A-Z0-9_-]*\.)*([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)/i', $_SERVER['SERVER_NAME'], $matches);
      if ($_GET['mode'] == 'ip')
      {
            if (is_numeric($matches[4]))  $host = $matches[0];            ## if $matches[4] is numeric, then host is IP
            else $host = '.'.$matches[3].$matches[4];
      } else $host = '.'.$matches[3].$matches[4];

      return $host;
}

?>
--------------------------



file 2: "test2.php"
--------------------------
<?php

if (!session_id())  session_start();

require_once($_SERVER['DOCUMENT_ROOT'].'/pointer_config.php');

if ($_GET['msg'])  $msg = urldecode($_GET['msg']);
echo $msg.'<br /><br />';

echo 'session_id='.session_id().'<br />';
echo '$_COOKIE['.session_name().']='.$_COOKIE[session_name()].'<br />';

echo '<br /><b>COOKIE VARS:</b><br>';
foreach ($_COOKIE as $key => $value)  echo $key.'='.$value.'<br>';

/*
the following links get session identifier added to them when running with
an IP based address, mode=ip, and -enable-trans-sid = 1, indicating that
server suddenly thinks browser is not accepting cookies.
*/
echo '<br /><br /><a href="test1.php">again?</a>';
echo '<br /><a href="test1.php?mode=ip">again with ip mode?</a>';
exit;

?>
--------------------------
0
Comment
Question by:merwetta1
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 6
15 Comments
 
LVL 6

Author Comment

by:merwetta1
ID: 17069499
this line in test2.php:
require_once($_SERVER['DOCUMENT_ROOT'].'/pointer_config.php');
is extraneous and doesn't need to be there
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069639
sessions are recognized using cookies

your browser should make a new cookie for a 'new' address, as to the browser the IP address is different to the DNS address

so you have to pass the session as a variable to the IP mode.
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069661
im not sure if this would work but setting the

session_id($id) might make php use the session of the dns site when going to the ip site..as long as you dont close the session

--

otherwise you can use session_encode and send that as a string (through get) to the ip mode and decode it on the otherside
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Author Comment

by:merwetta1
ID: 17069692
maUru, thanks for the response. I'm not trying to go from the domain to the IP, but just having problems when doing this all by IP. If you run the 2 files I provided using IP based addressing, when you click the "again with ip mode?" link, you should see that the session cookie has disappeared. I'm looking for an explanation of that.

I think any expert that wants to answer this question should try running the files to see what I'm talking about.
0
 
LVL 6

Author Comment

by:merwetta1
ID: 17069704
so if you run these scripts with IP addressing, when you first pull it up and when you click "try again", you see the session cookie is fine. when you click "try again with ip mode", the session cookie is gone. The only difference between the two is in the host used by setcookie(). why does one show the session cookie and the other not?
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069738
ah i see the problem

but then what is the point of ipmode, i mean removing this:

     preg_match('/^(([A-Z0-9][A-Z0-9_-]*\.)*([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)/i', $_SERVER['SERVER_NAME'], $matches);

     if ($_GET['mode'] == 'ip')
     {
          if (is_numeric($matches[4]))  $host = $matches[0];          ## if $matches[4] is numeric, then host is IP
          else $host = '.'.$matches[3].$matches[4];
     } else

makes it work.
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069746
my bad, was looking at wrong host
0
 
LVL 6

Author Comment

by:merwetta1
ID: 17069812
if $_GET['mode'] is not set to "ip" when running with an IP based address, then get_host() returns a truncated host name (i.e. ".12.34"), which I'm pretty sure means the browser won't clear the session cookie with the setcookie() call.

So in other words, without the mode=ip stuff, the session cookie never gets cleared in test1.php, which is not desirable, but cookies work fine after redirect to test2.php.

If $_GET['mode'] is set to "ip" when running with an IP based address, then full IP is returned by get_host, and session cookie is cleared by test1.php, but then PHP acts like cookies are disabled after redirect to test2.php.

Clearing the session cookie is having an adverse effect, but only with IP based addressing, and I want to understand why only with IP based addressing.
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069833
well even without IP mode, you are not setting the domain .bla.com for example

did you write this code or did you extract it from somewhere and try to manipulate it?
0
 
LVL 6

Author Comment

by:merwetta1
ID: 17069881
>well even without IP mode, you are not setting the domain .bla.com for example

not sure why you say that. when i run test1.php as http://www.mydomain.com/test1.php, the first line says:   host used='.mydomain.com'

the code is extracted from a login script I wrote myself.
0
 
LVL 7

Expert Comment

by:maUru
ID: 17069907
yes but the host used that you are echoing is from a function that removes the 3rd 4th tier of the domain

BUT

it is not actually being used anywhere, its not actually getting assigned to the PHPSESSID cookie, in fact, your PHPSESSID cookie (the setcookie line) is not even writing the session_id, so as far as this code is concerned, the host manipulation is redundant

if you could just explain what you are trying to do, i can give you a solution.
0
 
LVL 6

Author Comment

by:merwetta1
ID: 17070352
the host being echoed is used in this line:
setcookie(session_name(),'',time()-86400,"/", $host, 0);

I am executing that line because it's a good idea to clear the session cookie per
http://us2.php.net/manual/en/function.session-destroy.php

I use the get_host function to truncate the host to ".domain.com" because if a customer enters the site as "domain.com" and gets linked to "www.domain.com" somewhere along the line (or maybe it's vice versa?), cookies will not be available. This is my fix to a recurring problem of cookies only being available to subdomains.

I think it's reasonable to expect that my get_host() function would return the correct host string that the session cookie is using, and looking at the cookies confirms that. This routine has been working for a long time at a lot of sites not using IP based addressing. Now I want it to work with IP addresses, too. Because a lot of sites are depending on the routine, I can't just start from scratch.

Can you confirm that when you run the scripts under a domain name, ip mode shows the session cookie and when you run them under an IP address, ip mode loses the session cookie?
0
 
LVL 6

Author Comment

by:merwetta1
ID: 17070418
I changed one line in the get_host function and now it works perfectly.

if (is_numeric($matches[4]))  $host = '/';            ## if $matches[4] is numeric, then host is IP

So I revert to using "/" as the host, but only for IP based addresses. I'm guessing it's not right to pass an IP as the host in setcookie(). Problem solved.
0
 
LVL 5

Accepted Solution

by:
Netminder earned 0 total points
ID: 17118244
Closed, 500 points refunded.
Netminder
Site Admin
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
if (is_singular not working 5 39
PHP: Filling Out/Creating a PDF 29 107
Google Dork query 7 66
PHP $_POST vs asp request 4 28
Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
Many old projects have bad code, but the budget doesn't exist to rewrite the codebase. You can update this code to be safer by introducing contemporary input validation, sanitation, and safer database queries.
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question