JS Solicitor – PostMessage API

Engineering

Learn from our challenges and triumphs as our talented engineering team offers insights for discussion and sharing.

JS Solicitor – PostMessage API

Engineering

Motivations

LiveRamp’s traditional web personalization technologies have always integrated with our partners’ web servers. (i.e. we send anonymous data on the consumers viewing a webpage to the partner’s web server for the generation of personalized content). We’ve recently developed a new type of integration that allows us to securely send this data directly to the web browser so that personalized content can be generated with javascript. This blog posts explain how we’ve accomplished this.

For years, our client-side data delivery has been using the traditional pixel redirect mechanism. Our publisher integrates our tag (an invisible HTML element) on its website, and whenever a browser loads the page it triggers a request to our servers. When we receive this request, we return a redirect response to our partner’s web server with anonymous consumer data on the current visitor attached to the url.

PostMessage_Blog_Post_2__png

Some customers recently came to us with a new use case. They wanted to make the data directly available on the page so that it can be used for A/B testing or content personalization.

The main limitation with our current implementation is that it only allows the data to be sent to our partner servers, inaccessible to the user’s browser. Indeed, since the data is delivered with redirects the host page is unable to see the transmitted data.

We decided to make the data available through a javascript object on the page. This requires us to add a javascript tag on the website’s pages and then provide the javascript object through this tag. A javascript tag is a piece of code that allows the execution of custom code on the browser and the manipulation of javascript objects.

There is an important factor to take into account when exposing data through javascript. We need to ensure that no one other than the authorized website can read the data. If you don’t protect against that, any website could read all data on their visitors by just including the tag on their page and reading the JS object.

Available Options

Referrer header check

One simple solution would be to return the JS object if the request Referrer header is coming from a whitelisted domain. The main problem with that kind of validation is that Referrer is an optional header. Not all the devices/browsers will send it and some browser privacy settings will remove this information from the request.

Cross-Origin Resource sharing (CORS)

A good way to verify the source of the request is to take advantage of the built-in browser security that prevents X-origin interactions. By default all these interactions are blacklisted, but you can enable them on a case-by-case basis using the CORS API which is implemented in most of the recent browsers.

To simplify how it works, the browser would make an initial authorization request to our server, then we would allow or forbid subsequent requests to our API.

This is an elegant solution that we considered, but it would introduce extra traffic to our servers and require more engineering work to build a new authorization servlet.

PostMessage (API)

With this solution we take advantage of the built-in browser security using an API that is implemented in the most recent browsers. It enables X-Origin interactions and the whitelisting works in both directions: the partner’s website whitelists us and we whitelist them.This solution requires little effort for the partner and it doesn’t require any architectural changes on our side.

We chose this solution.

Implementation

The PostMessage implementation consists of two components:

Posting the data

When a website implements this solution to access data, they integrate our javascript tag on their page and it will automatically send a request to our servers.

When we receive the request, we generate a javascript response which contains the call to the PostMessage API with the JS object and the authorized domain.

There is no authorization logic on the server since everything is handled by the browser’s internals.

Here is what the response looks like:

parent.postMessage(["seg1","seg1"], "http://partner.com");

postMessage is the API exposed by the browser.

The first parameter is the data that we want to make accessible on the page. It can be of any type, except on earlier versions of IE where it can only be a string.

The second parameter is the domain allowed to receive the message. If the call is coming from an unauthorized domain the postMessage call will just fail and the data will remain inaccessible.

Receiving the data

The website integrating our solution needs to whitelist us and the pages that integrate with us must setup the receiving mechanism. To do so, they add an event listener on “message” and whitelist our domain.

function eventHandler(event) {
  // Whitelist our domain
  if (event.origin !== "http://receiverdomain.com") {
    return;
  }
  console.log(event.data); // event.data is JS array: ["seg1","seg1"]
}

if(window.addEventListener) {
  window.addEventListener("message", eventHandler, false);
} else { // IE
  window.attachEvent("onmessage", eventHandler);
}

Note: There is a small difference between IE and other browsers’ APIs.

New client-side workflow

Screenshot_10_13_15__11_43_PM

Limitations

  • You can only whitelist one domain at a time,
  • Some older browsers don’t support this API (IE < 7, Firefox < 3, Safari < 4…)

Conclusion

This new and secure way of transmitting data to a page enables a whole new set of use cases, and with the need for more real time site customization, this data delivery mechanism is becoming more popular among our customers. It also integrated very nicely with our current infrastructure.

Current LiveRamp customers can find more information in the LiveRamp Resource Center.