Skip to content

How to Track your Users over Several Domains?

October 14, 2016Charles BOCHET4 min read

Track users over different domains is a recurrent issue while developing a substantial web solution. Use cases are countless:

  • authenticate customers over different websites (Google-like single sign-on);
  • cross-sell based on what they have visited previously on other websites;
  • customize user experience;
  • analytics.

Let's say we are trying to build a single authentication between two domains: and
We are considering the following scenario, following a specific user named Jack:

User tracking scenario

How can we get to know that its users are already logged in on

Setting cross-domain cookies?

The first approach that comes to mind is to set a cookie on users' web browser as soon as they are authenticated on this website and to use these cookies later on
At first glance, this solution seems staight-forward: setting a cookie is easy and can be achieve within a few lines of codes using PHP or JS.

setcookie("loggedIn", true);

Unfortunately, here we encounter our first problem:
There is an important web concept called 'Same origin policy' that prevents one website to access another website resources through user's browser.
Amongst other things, this rule specify that cookies are specific to a given domain. Nor is able to read related cookies, nor is capable of writing its own on
And this for user security purposes: you don't want a malicious page to get access session cookies.

So, how do we deal with this problem? How does Google, Microsoft & Co deal with it?

The wrong way: using AJAX requests (CORS)

OK, cookies are tied to a specific domain. Why not using a custom-made AJAX request from on and forcing to settle its own cookie?

Using Ajax Requests

We can implement this interaction within a few line on both sides:


var xmlHttp = new XMLHttpRequest();"GET", "", true);

set-authentication-cookie.php on :

setcookie("loggedIn", true);

And... this is unsuccessful! After visiting, no cookie is set on
We should have a look at JS console:

XMLHttpRequest cannot load
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin '' is therefore not allowed access.

Browsers are a lot smarter than we first thought.
As we said, requests are restricted by the same-origin policy that prevents web browsers from executing code coming from another domain.
However this prevents legitimate behaviors between domains too even if domains are known and trusted.

What about CORS ?

Cross-origin resource sharing (CORS) is a W3C system that enables a given domain to request some resources (stylesheets, images, css, scripts...) from another domain.
CORS are built on top of XMLHttpRequest(). It actually softens same-origin policy to enable cross-domain requests. Of course, it needs some coordination between servers.

We need to add the following attribute to AJAX script:

xmlHttp.withCredentials = true

And specific headers to target PHP page:

header('Access-Control-Allow-Credentials: true');

As soon as you do so, we should be able to perform our AJAX request:

var xmlHttp = new XMLHttpRequest();"GET", "", true);
xmlHttp.withCredentials = true;

header('Access-Control-Allow-Credentials: true');
setcookie("loggedIn", true);

And... seems to works! As we navigate on, a loggedIn cookie is set on for later use.

Time for bad news

This approach is effective as long as third-party cookies are allowed in client configuration.
If Firefox and Chrome authorize third-party cookies by default, IE9+/Edge and Safari are far more susceptible.

Safari use enforced cookies policy that disable third-party cookies, plain and simple.

Internet Explorer (as usual) follows its own rules. It refuses such cookies unless you are using a P3P policy.
P3P is an old, deserted and unfinished (Firefox has given up supporting it) W3C spec and I won't recommend using it.

As we can't obviously ask our users to modify their settings for us, we are therefore at an impasse.

Futhermore, it doesn't matter what technical solution we choose: AJAX request, tag, JS script, iframe...
Even if we find a workaround, it won't be a sustainable solution since browsers will likely fix it later.

The right way: using HTTP Redirections

Asynchronous requests don't seem to do the trick. What about synchronous ones?
We need to perform two consecutive redirections and set cookies for each domain when needed:

Using redirections

This approach is transparent and painless for the user. It requires no Javascript and don't rely upon browser configuration:

index.php on

if (!isset($_COOKIE['alreadyRedirected'])) {
setcookie("alreadyRedirected", true);

set-authentication-cookie.php on

setcookie("loggedIn", true);

This time, loggedIn cookie is set and available on once user has visited page.
Best solutions are often simpler than we think, aren't they?


CORS requests is a powerful tool to perform cross-domain requests.
Nevertheless, it's not suitable for implementing cross-domain or third-party cookies because of some browsers default settings (Safari and IE/Edge).

HTTP redirections turns out to be the easiest and the most effective way of creating a single sign-on system.
This approach can easily be generalized: have fun tracking users over multiple websites!