Take the 2-minute tour ×
Webmasters Stack Exchange is a question and answer site for pro webmasters. It's 100% free, no registration required.

The short version:

I've got a session cookie being set on a dev site but it's not being picked up when I move to the SSL (so the shopping cart empties when you go to the checkout).

When it's set on the www site:

# http://dev.domain.ext
Name    devSID
Value   2e9f1b1f6ca718d0961d0257f3297c1a
Host    .domain.ext
Path    /
Secure  No
Expires At End Of Session

And on the ssl side:

# https://dev.domain.ext
Name    devSID
Value   6fe74ccc91b67bce46165d005bfd157e
Host    .domain.ext
Path    /
Secure  No
Expires At End Of Session

It looks like the session cookie created under www isn't being picked up under the ssl side (conversely it doesn't go the other way either, if it's created on the ssl side it's not picked up on the www side).

Anyone got any bright ideas?


The long version (me working it through)

I've got a dev site currently on a dev sub-domain; the session cookie being set is accessible across the whole domain using a .domain.ext type format and is created using a PHP object which loads the parameters from a config table in the database.

The same object creates the cookie across all sub-domains so it's not creating duplicate cookies with different path values or anything like that.

Name    devSID
Value   [alpha-numeric hash value]
Host    .domain.ext
Path    /
Secure  No
Expires At End Of Session

On my local machine the sub-domains used are www and ssl so the host string reads as .dev.local and the cookie is happily read across the entire domain (using Apache's https-vhosts.conf to setup the domains on the server and the Windows hosts file to point them to 127.0.0.1)... and everything is peachy.

However, when I upload it to an online dev server (with it's own config and vhosts settings) the cookie gets dropped when moving from the www to ssl sides of the site and I can't see any logical reason for it.

This is what's going on in vhosts:

<VirtualHost [IP ADDRESS]:80 >
    ServerName www.dev.domain.ext
    ServerAlias www.dev.domain.ext dev.domain.ext

    ...
</VirtualHost>

<VirtualHost [IP ADDRESS]:443 >
    [SSL ENGINE BIT]

    ServerName ssl.dev.domain.ext
    ServerAlias ssl.dev.domain.ext dev.domain.ext

    ...
</VirtualHost>

Technically the sub-domains (as defined by ServerName) are www.dev and ssl.dev however neither of those are actually registered with any DNS servers - the DNS servers just have the higher dev sub-domain registered; so I've added that into the ServerAlias list and entries have been made in my Windows hosts file so the unregistered sub-domains resolve on my machine.

[IP ADDRESS]    www.dev.domain.ext
[IP ADDRESS]    ssl.dev.domain.ext

And the session cookie parameters:

Name    devSID
Value   [alpha-numeric hash value]
Host    .domain.ext
Path    /
Secure  No
Expires At End Of Session

So theoretically that cookie should be accessible across all sub-domains (even the live site actually since I've not limited it to the dev sub-domain) but whenever I move to the SSL side the cookie gets dropped.

share|improve this question
add comment

3 Answers 3

up vote 1 down vote accepted

OK - I think I've just solved it, thanks to Dave and Emil; whilst you didn't hit the nail on the head - you did make me look in the right sort of place (and reminded me of Fiddler to debug).

Theoretically, what I was doing should not have broken the cookie but it was, but only sometimes (e.g. it worked fine accessing the online dev server from home but not from the office)...

Basically, PHP's session cookie control session_set_cookie_params() doesn't handle non-zero expiry dates in the way I'd like; if you set the session to expire in 15 minutes, time() + 900 it will expire in 15 minutes from when the cookie is set - it will not update the expiry time. So what I was doing, inside the private constructor of my Session object (it's a Singleton), was:

if($this->cookie_lifetime != 0) {
      if(is_null($bUseHTTPCookie)) { setcookie($this->getName(), $this->getID(), (time() + $this->cookie_lifetime), $this->cookie_path, $this->cookie_domain, $this->use_ssl_cookie_only); }
      else { setcookie($this->getName(), $this->getID(), (time() + $this->cookie_lifetime), $this->cookie_path, $this->cookie_domain, $this->use_ssl_cookie_only, $this->use_http_cookie_only); }
}

Which is supposed to update the session cookie to extend the time by 15 minutes whenever the page is refreshed; and it was working fine locally and accessing the dev server from home but was not working from my machine at work (it might work one time in about 50).

I suspect it's a latency issue; that somehow on my creaky machine in my creaky office the time taken for session_set_cookie_params() to actually write the cookie may have been long enough for the script to hit the setcookie() that's supposed to update that cookie ... and bad things happened.

I noticed, in Fiddler, that when one page took a long time to load the session cookie wasn't set, which implies that setcookie() was running before the session id was in place and therefore setting an empty string as the value of the cookie... which will, of course, delete the cookie.

Now I've commented out the setcookie() function(s) it seems to be working from the office!

Yes, no need to tell me, I'm an idiot - thank you :)

share|improve this answer
add comment

I will suspect this is something to do with the cookie domain. Try creating a script with a call to the phpinfo() function, and inspect the value of the session.cookie_domain value on both the www and ssl vhosts?

share|improve this answer
    
Nope - it's something much stranger than that... I'm beginning to narrow it down to either something Windows XP specific or something to do with our office network - because it'll work fine on a Windows 7 machine outside this network I discovered last night; it might be some kind of domain conflict with our VPN to Holland but I'm not sure. I think this might turn out to be too case-specific to really be solved on stackexchange :\ –  CD001 Oct 21 '11 at 13:52
2  
Try something like Fiddler Web Debugger to see the different HTTP request in the different environments? –  Emil Rasmussen Oct 21 '11 at 14:55
    
Might not have quite solved it ... but +1 on the Fiddler comment (I'd completely forgotten about it); there's definitely something strange going on as it seems the devSID cookie is being reset 3 times under the SSL shell - which shouldn't be possible as session_start() is called in a private constructor in a Singleton pattern! –  CD001 Oct 24 '11 at 11:45
    
Interesting problem you had there. Glad my suggestion could help you on your way :-) –  Emil Rasmussen Oct 26 '11 at 12:58
add comment

You are looking under the wrong assumption. When changing from http to https, its treated as a new domain, new server, new everything, so cookies cannot be maintained between ssl and non-ssl connection, despite they are on the same server, same domain.

A solution for this change is using a query string redirect. For example:

You are on http:/www.domain.tld and have a session associated session cookie PHPSESSID=123

In the links for changing server you should add a query string like https://secure.domain.tld/?key=876 - suppose it is a md5 hash of cookie value.

When user clicks and reaches the https connection you should be able to identify this query string and load the correct session he was using on non-ssl navigation.

This should solve your problem.

share|improve this answer
1  
Umm - no, basically. You can quite happily pass a cookie with the domain .mydomain.ext between https://secure.mydomain.ext and http://www.mydomain.ext - the worst that will happen is that something like McAfee Secure might report it as a low level security vulnerability (unencrypted cookie accessed in secure domain)... cookies aren't that clever. –  CD001 Oct 24 '11 at 11:28
    
Well, seems there are some misleading points in your question and my answer. What I was trying to say was proven to be true as many people responded the same thing with much more authority. Please check: stackoverflow.com/questions/441496/… and stackoverflow.com/questions/5921545/… . This should solve your problem. –  Dave Oct 24 '11 at 22:33
    
... actually - I'd covered all those bases - but I think I've just solved it; and I think I may have done something a little daft ... You did point me in the direction of taking another, really good look at my session handling object though - thanks! :) –  CD001 Oct 25 '11 at 11:44
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.