Solved

disappearing session cookie with IP based address

Posted on 2006-07-09
15
330 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
  • 7
  • 6
15 Comments
 
LVL 6

Author Comment

by:merwetta1
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 6

Author Comment

by:merwetta1
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
my bad, was looking at wrong host
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 6

Author Comment

by:merwetta1
Comment Utility
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
Comment Utility
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
Comment Utility
>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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Closed, 500 points refunded.
Netminder
Site Admin
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This article will explain how to display the first page of your Microsoft Word documents (e.g. .doc, .docx, etc...) as images in a web page programatically. I have scoured the web on a way to do this unsuccessfully. The goal is to produce something …
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

743 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

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now