Sharing session data across domains with PHP

The problem: Multiple domains hosted on one server needed access to the user’s session data. In my case, various shopping domains were sharing one (SSL-enabled) domain where the users could place their orders.

The solution I found was surprisingly simple: Since these domains were hosted on the same server and used the same session save path, I was wondering if I could simply pass the existing session ID along to the new domain in order to give it access to the corresponding session file. Indeed all it took was a hidden form field containing the session ID and something like “session_id($_POST[‘SID’])” on top of the first page of the ssl-domain (before session_start()). Voilà, the old session ID was also the new one and the ssl-domain could continue working with the session data.

On top of that, if the user returned to the previous domain (anywhere!), his – possibly updated – session data was still available there, too (unless he had somehow deleted the session cookie). If I had opted to actually pass the session data between domains and not just the ID, this “seamless” user experience would’ve been harder to achieve.

Now where’s the catch? Well – obviously – once business takes off and several servers become necessary to handle the load, I’ll be cursing myself for not implementing a databased-based* solution for session management like the one mentioned in recipe 11.4. of the PHP Cookbook.

*“Database-based” sounds really bad, no wonder it’s “database-aware” in the book. Can I call it “databased”? 🙂

Back to reality, on a managed or shared server there’s always the danger of the admin breaking this simple solution. The obvious candidate for disaster would be the session save path, which has to be the same for all domains (but hopefully different from other client’s paths). A way more obscure modification by my webhost caused some panic this morning: the suhosin.session.cryptdocroot flag was apparently set to “on” and did what it was designed to do, forcing the ssl-domain to start a new session file and thereby overwriting the customers’ shopping carts once they tried to check out.

12 thoughts on “Sharing session data across domains with PHP”

  1. I’m glad I found this web page because the other web pages were having you jump through hoops to do the same thing. I did try setting the session_id(my_session_id) before I came to this website, but I didn’t try it before session_start(). That made all the difference. Thanks.

  2. Sorry for my late reply. There’s really not much to it:
    1. On domain A, get the current session ID:
    $SID=session_id();
    2. Use GET or POST to send the session ID to domain B together with the user, e.g. by saving it in a hidden form field:
    input name="current_session_id" type="hidden" value="$SID"
    3. On domain B, the very first thing you have to do is to set the session ID to the value that was passed along from domain A:
    if (!empty($_POST['current_session_id'])) session_id($_POST['current_session_id']);
    session_start();

    Hope this helps.

  3. Hi Stephan,
    Did it ever occur to you that the session id can be read in the source of the website ?
    A hidden field is not shown but can be easily read ! I’lld regard this as a very unsafe method.

  4. Doesn’t work here, unfortunately. The session data is not read on the other domain after passing it via GET and calling session_id() with the ID. Too bad.

  5. I have been doing this solution for years and it has always worked. However it has now been brought to my attention that it is very easy to session hi-jack a session using this method however unlikely it is still a security concern. I am in search of a new method at this time.

  6. At the top of each file, I have a cfg.php include that sets a bunch of constants to be used system wide. In both domains I have:

    ob_start();
    if (!empty($_GET[‘current_session_id’])) session_id($_GET[‘current_session_id’]);
    session_start();

    I don’t bother with a variable. In the calling link I have:

    https://domain_B.com/index.php?current_session_id=

    And this seems to work fine; the same number appears in the address bar both ways, but this makes me nervous, I changed the $_GET to $_POST and use this to call the other domain:

    <input name = "current_session_id" type = "hidden" value = "” />

    And I get a security warning. If I push the issue, the second domain refuses to load and some message about maintenance appears. Called directly, it loads okay.

    Any ideas what I’m doing wrong? I don’t want the session id out in plain sight, but, for the moment, I’m not worried about someone hijacking a $_POST-passed id.

Leave a Reply