未加星标

How to Track your Users over Several Domains?

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二03 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

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: my-account.com and webmail.com .

We are considering the following scenario, following a specific user named Jack:


How to Track your Users over Several Domains?

How can we get webmail.com to know that its users are already logged in on my-account.com ?

Setting cross-domain cookies?

The first approach that comes to mind is to set a cookie on my-account.com users’ web browser as soon as they are authenticated on this website and to use these cookies later on webmail.com .

At first glance, this solution seems staight-forward: setting a cookie is easy and can be achieve within a few lines of codes usingphp or JS.

<?php
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 webmail.com is able to read my-account.com related cookies, nor my-account.com is capable of writing its own on webmail.com .

And this for user security purposes: you don’t want a malicious page to get access my-bank-account.com 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 my-account.com on webmail.com and forcing webmail.com to settle its own cookie?


How to Track your Users over Several Domains?

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

On my-account.com :

var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "http://webmail.com/set-authentication-cookie.php", true);
xmlHttp.send(null);

set-authentication-cookie.php on webmail.com :

<?php
setcookie("loggedIn", true);

And… this is unsuccessful! After visiting my-account.com , no cookie is set on webmail.com .

We should have a look at JS console:

XMLHttpRequest cannot load http://webmail.com/set-authentication-cookie.php.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://account.com' 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');
header('Access-Control-Allow-Origin: my-account.com');

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

my-account.com :

var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "http://webmail.com/set-authentication-cookie.php", true);
xmlHttp.withCredentials = true;
xmlHttp.send(null);

webmail.com :

<?php
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Origin: http://my-account.com');
setcookie("loggedIn", true);

And… seems to works! As we navigate on my-account.com , a loggedIn cookie is set on webmail.com 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, <img> 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:


How to Track your Users over Several Domains?

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

index.php on my-account.com:

<?php
if (!isset($_COOKIE['alreadyRedirected'])) {
setcookie("alreadyRedirected", true);
header('Location: http://webmail.com/set-authentication-cookie.php');
}

set-authentication-cookie.php on my-account.com :

><?php
setcookie("loggedIn", true);
header('Location: http://account.com/index.php');

This time, loggedIn cookie is set and available on webmail.com once user has visited my-account.com page.

Best solutions are often simpler than we think, aren’t they?

Conclusions

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!

Post Views: 16

You liked this article? You'd probably be a good match for our ever-growing tech team at Theodo.

Join Us

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: XMLPHPJavaChromeFirefox
分页:12
转载请注明
本文标题:How to Track your Users over Several Domains?
本站链接:http://www.codesec.net/view/482861.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(25)