Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

disappearing session cookie with IP based address

Posted on 2006-07-09
15
Medium Priority
?
343 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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

Ask an Anonymous Question!

Don't feel intimidated by what you don't know. Ask your question anonymously. It's easy! Learn more and upgrade.

Question has a verified solution.

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

These days socially coordinated efforts have turned into a critical requirement for enterprises.
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
Suggested Courses

636 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