Best way to handle PHP sessions across Apache vhost wildcard domains

apache-2.2php.inivirtualhostwildcard-subdomain

I'm currently running a site that allows users to use custom domains (i.e. so instead of mysite.com/myaccount, they could have myaccount.com). They just change the A record of their domain and we then use a wildcard vhost on Apache to catch the requests from the custom domains. The setup is basically as seen below. The first vhost catches the mysite.com/myaccount requests and the second would be used for myaccount.com. As you can see, they have the exact same path and php cookie_domain.

I've noticed some weird behavior surrounding the line below "#The line below me". When active, the custom domains get a new session_id every page load (that isn't the same as the non-custom domain session). However, when I comment that line out, the user keeps the same session_id on each page load, but that session_id is not the same as the one they'd see on a non-custom domain site either despite being completely on the same server.

There is a sort of "hack" workaround involving redirecting the user to mysite.com/myaccount, getting the session ID, redirecting back to myaccount.com, and then using that ID on the myaccount.com. But that can get kind of messy (i.e. if the user logs out of mysite.com/myaccount, how does myaccount.com know?).

For what it's worth, I'm using a database to manage the sessions (i.e. so there's no issues with being on different servers, etc, but that's irrelevant since we only use one server to handle all requests currently anyways).

I'm fairly certain it is related to some sort of CSRF browser protection thing, but shouldn't it be smart enough to know it's on the same server?

Note: These are subdomains, they're separate domains entirely (but on the same server).

<VirtualHost *:80>
    DocumentRoot "/opt/local/www/mysite.com"
    ServerName mysite.local
    ErrorLog "/opt/local/apache2/logs/mysite.com-error.log"
    CustomLog "/opt/local/apache2/logs/mysite.com-access.log" common
        <Directory "/opt/local/www/mysite.com">
                AllowOverride All
                #php_value session.save_path "/opt/local/www/mysite.com/sessions"
                php_value session.cookie_domain "mysite.local"
                php_value auto_prepend_file "/opt/local/www/mysite.com/core.php"
        </Directory>
</VirtualHost>

#Wildcard (custom domain) vhost
<VirtualHost *:80>
    DocumentRoot "/opt/local/www/mysite.com"
    ServerName default
    ServerAlias *
    ErrorLog "/opt/local/apache2/logs/mysite.com-error.log"
    CustomLog "/opt/local/apache2/logs/mysite.com-access.log" common
        <Directory "/opt/local/www/mysite.com">
                AllowOverride All
                #php_value session.save_path "/opt/local/www/mysite.com/sessions"
                # The line below me
                php_value session.cookie_domain "mysite.local"
                php_value auto_prepend_file "/opt/local/www/mysite.com/core.php"
        </Directory>
</VirtualHost>

Best Answer

Surely you could do it pretty easily by passing the SID between the domains?

The key is session transfer - how you execute it is up to you.

Either via GET using SID, or maybe at the application level. Where you have a DB table with a combination hashed identifier (IP + UserAgent + OS etc.) and corresponding SID. Then you could "detect" the user - match the identifier and set the appropriate session.

However if it isn't executed properly, you could either end up with session hijacking or outight session loss.

Alternatively a nicer way would be perhaps to use a 3rd party site/service for authentication (OpenID/Google/Facebook/Twitter etc.). Then you could use that to tally up with the respective server-side session.

Related Topic