iovation - Web

❗️

Bazaarvoice clients and partners only. All others should refer to iovation for documentation.

🚧

This version of iovation's integration is the newest. You can find documentation for the previous version here.

This tutorial demonstrates how to create and submit device fingerprint information from iovation along with user generated content to the Bazaarvoice Conversations API.

Introduction

Mass advertising campaigns, trolling, and attempts at automated content submission are all sources of inauthentic content. To combat them Bazaarvoice has partnered with iovation, an industry leader in fraud detection and prevention.

iovation fraud detection and prevention

To prevent and detect fraud in the webbrowser iovation's has developed a JavaScript based solution that generates an encoded device fingerprint string - aka black box - containing information about the end-user's computing device such as OS, browser, etc (no PII is exchanged or maintained). This device fingerprint black box string is used in conjunction with sophisticated algorithms allowing Bazaarvoice to identify, flag and report suspicious content.
Without this information our fraud detection technology will not be able to identify submissions as authentic consumer generated content.

🚧

Per the Bazaarvoice Authenticity Policy, you must send a device fingerprint attached to each submission. If you fail to send a device fingerprint with your submission, Bazaarvoice may take any action deemed necessary in Bazaarvoice’s sole discretion to protect the integrity of the network. Such actions may include but are not limited to: rejection of your content, halting syndication of your content on the Bazaarvoice network, revocation of your API key, or revocation of your API license.

Integration summary

There a two components to iovation's fraud prevention and detection integration:

  • JavaScript: You will host ioation's loader JavaScript which will load additional resources used to generate a device fingerprint blackbox string.
  • Server: An optional server side proxy that you implement to send first party requests for iovation resources from your domain to iovation. This makes it appear as if iovation's assets are coming from your domain so they are not rejected by script blockers.

🚧

We don't require the server side intergation, but you may implement it if you want. Refer to the server integration section below to learn more.

The following list is a step-by-step overview of the process for collecting device information. It assumes a client side environment that supports JavaScript, such as a web browser:

Step-by-step overview

  1. Configure and load iovation's JavaScript library in your web app.
  2. Wait for iovation's script to analyze the user agent and create a device fingerprint black box string.
  3. Submit to the Bazaarvoice Conversations API including the fp parameter with the iovation black box value.

Acquiring iovation's JavaScript

You will need to host iovation's JavaScript loader file. You can get the file in one of the following ways:

  • If you are currently assigned an Implementation team, then you can contact your Implementation Engineer.
  • If you already have an account at our Support Community, then you can access the loader file directly at the following URL: https://support.bazaarvoice.com/s/article/iovation-web
  • If neither the above apply, then you should contact our Support team

Continue reading to learn about the different JavaScript integration options provided by iovation and how to use them in conjunction with the Bazaarvoice Conversations API.

JavaScript integrations

Use one of the following integration methods to add iovation to your website:

This is the easiest technique, but it offers the least flexibility. It will only work with one form on the page and the form must be on the page before iovation's JavaScript is loaded.

  1. Create form field for device fingerprint black box
<form action="http://yourdomain.example.com/path/to/your/service" method="post">
  <!-- Your other form fields here -->
  <input type="hidden" name="blackBox" id="ioBlackBox"/>
 </form>       
  1. Configure iovation's JavaScript

Configurations must be on page before iovation's JavaScript loads.

window.IGLOO = window.IGLOO || {
            "bbout_element_id" : "ioBlackBox",    // Populate #ioBlackBox input with device fingerprint
            "enable_rip" : true,                 // Enable Real IP protection.
            "enable_flash" : false,              // Disable flash
            "install_flash" : false,             // Don't ask user to install flash
            "loader" : {
              "version" : "general5",            // Non-experimental 5.x updates
              "fp_static" : false                // Don't load 1st party resources
            }
          };

🚧

Remove "fp_static" : false if you intend to implement the server integration.

  1. Serve iovation's JavaScript loader

You should host and serve iovation's JavaScript loader from your domain. iovation's loader will load the additional scripts and resources necessary to generate a device fingerprint.

<script src="https://yourdomain.example.com/path/to/iovation/loader.js"></script>

Somewhat more complex than the hidden form field option, but provides useful information about when the black box string is available.

  1. Configure iovation's JavaScript

Configurations must be on page before iovation's JavaScript loads.

 window.IGLOO = window.IGLOO || {
            "enable_rip" : true,                 // Enable Real IP protection.
            "enable_flash" : false,              // Disable flash
            "install_flash" : false,             // Don't ask user to install flash
            "loader" : {
              "version" : "general5",            // Non-experimental 5.x updates
              "fp_static" : false                // Don't load 1st party resources
            }
          };

🚧

Remove "fp_static" : false if you intend to implement the server integration.

  1. Define bb_callback()
window.IGLOO.bb_callback = function(blackBoxString, isComplete) {
            if (isComplete) {
              // Your code to handle blackBoxString
            }
          }          

🚧

The bb_callback() function may generate several black box strings in rapid succession. Each string will contain more device fingerprinting information than the last. When the user submits their content, you should use the most recently generated blackbox string.

  1. Serve iovation's JavaScript loader

You should host and serve iovation's JavaScript loader from your domain. iovation's loader will load the additional scripts and resources necessary to generate a device fingerprint.

<script src="https://yourdomain.example.com/path/to/iovation/loader.js"></script>

This method offers the most information and control however it is also the most complex because each object returned by getBlackBox() is unique, so getBlackBox() may need to be executed several times until the black box string is available.

  1. Configure iovation's JavaScript

Configurations must be on page before iovation's JavaScript loads.

window.IGLOO = window.IGLOO || {
            "enable_rip" : true,                 // Enable Real IP protection.
            "enable_flash" : false,              // Disable flash
            "install_flash" : false,             // Don't ask user to install flash
            "loader" : {
              "version" : "general5",            // Non-experimental 5.x updates
              "fp_static" : false                // Don't load 1st party resources
            }
          };

🚧

Remove "fp_static" : false if you intend to implement the server integration.

  1. Serve iovation's JavaScript loader

You should host and serve iovation's JavaScript loader from your domain. iovation's loader will load the additional scripts and resources necessary to generate a device fingerprint.

<script src="https://yourdomain.example.com/path/to/iovation/loader.js"></script>
  1. Query getBlackBox for information

Each call to ioGetBlackbox() returns a JavaScript object with information about the current state of the black box and eventually the black box string itself.

var timeoutId;

function useBlackboxString(intervalCount) {
 if (typeof window.IGLOO.getBlackbox !== 'function') {return;}

 var bbData = window.IGLOO.getBlackbox();
 if (bbData.finished) {
     clearTimeout(timeoutId);
     var blackBoxString = bbData.blackbox;
     // Your code to handle blackBoxString
    }
  }
  timeoutId = setInterval(useBlackboxString, 500);          

Consider limiting your useBlackboxString function to a fixed number of executions after which you assume the black box string is unavailable.


Once you're able to generate a device fingerprint black box string, you can then submit it to Bazaarvoice along with the author's content.

Submitting device fingerprint to Bazaarvoice

The iovation device fingerprint black box string must be communicated to Bazaarvoice using the fp parameter along with the user's content.

Parameters

NameDescriptionDefault Value
fpValue is iovation device fingerprint black box string.N/A

Content types

The fp parameter is available for the following content types.

  • Review
  • Review Comment
  • Question
  • Answer

Example

Submission should be performed using the HTTP POST method with a request body due to the length of the black box string and limitations imposed on query string length by some servers.

The example below shows a submission including a the fp parameter.

📘

The following code applies to full submission only. It does not apply to progressive submission.

POST /data/submitreview.json HTTP/1.1
Host: stg.api.bazaarvoice.com
Content-Type: application/x-www-form-urlencoded
X-Forwarded-For: [AuthorIPAddress]


rating=5&title=This+is+a+review+title&reviewtext=This+is+review+text.+This+is+review+text.+This+is+review+text.+This+is+review+text.+This+is+review+text.+This+is+review+text.+This+is+review+text.+&UserNickname=bvtester&productId=io_bb_callback&userId=1234567&apiversion=5.4&action=submit&passkey=hk5pv3pfasrrdjyq487m699s&fp=[BlackBoxString]

Ellipses (…) in above example indicate that your app may generate other headers.

Encoding the blackbox string

❗️

Failure to correctly encode the black box string will result in your content being considered inauthentic.

The black box string contains characters that are reserved for special purposes in a URI. For example, the plus sign (+) is an encoding for the white space character. Because submission is performed using the Content-Type: application/x-www-form-urlencoded header, our application will decode the black box string and interpret a plus sign as a white space character.

To correctly submit the black box string, you must ensure that the black box string is itself percent encoded, so that any reserved characters are not misinterpreted. For example, the percent encoding for a plus sign is %2B. When our application encounter that sequence of characters, it will be interpreted as a + character.

The following examples demonstrate unencoded and encoded black box strings:

Unencoded

The black box string depicted in this example should not be submitted to Bazaarvoice because it is not encoded.

0400mTR4Z7+BQcwNf94lis1ztli3mJEkJyoNdUgbrAJXB1FL4OEJMXZmD5jK1MaVRDhlAQ9qVcA9LW6vVIn0Up+4mzLLK7Xd4mGlEKa0Y+mB3pcCMqvMh8qRwB6l1hlSasV82UeoAtphovcW/PXBDOAZObSUZpybFcXAARVnJuq5mFWxH1ZPRIwM6iaikdE2N/iBS7gHh9oerxrosS1xgSAgNfLEMokGoGJxq3nJn2qrpH3U8XBpd1sDgWA73rYZtIsVyoA80pXCaXYch6NDTeqGONC1UJgA1BQZDi8R6wVNV9r6qoxEqm2gQ71/Y9e8eiB48zOQG3Lx3BMX0E/AY6vmjxNpiXJ/hZ…

Ellipses (…) indicated that the string has been shortened for demonstration purposes.

Encoded

This black box string is encoded and is safe to submit to Bazaarvoice.

0400mTR4Z7%2BBQcwNf94lis1ztli3mJEkJyoNdUgbrAJXB1FL4OEJMXZmD5jK1MaVRDhlAQ9qVcA9LW6vVIn0Up%2B4mzLLK7Xd4mGlEKa0Y%2BmB3pcCMqvMh8qRwB6l1hlSasV82UeoAtphovcW%2FPXBDOAZObSUZpybFcXAARVnJuq5mFWxH1ZPRIwM6iaikdE2N%2FiBS7gHh9oerxrosS1xgSAgNfLEMokGoGJxq3nJn2qrpH3U8XBpd1sDgWA73rYZtIsVyoA80pXCaXYch6NDTeqGONC1UJgA1BQZDi8R6wVNV9r6qoxEqm2gQ71%2FY9e8eiB48zOQG3Lx3BMX0E%2FAY6vmjxNpiXJ%2FhZ…

Ellipses (…) indicated that the string has been shortened for demonstration purposes.

Refer to the Appendix to see code examples depicting how to properly encode the black box string.

Encoding code examples

These examples demonstrate how to encode submission data. Refer to the Submission Fundamentals guide for more information about performing a submission.

Plain JavaScript

You must encode the values yourself when using plain JavaScript. Learn more about encodeURIComponent().

var title = encodeURIComponent('This is an example submission');
var blackBoxString = encodeURIComponent('0400mTR4Z7+BQcwNf94lis1ztli…');

var http = new XMLHttpRequest();
http.open('POST', 'https://developer.bazaarvoice.com/data/submitreview.json');
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function () {…}
http.send('rating=5&title=' + title + '&fp=' + blackBoxString);

jQuery

Object method

If you pass submission data as an object, jQuery will automatically encode the values for you.

var jqxhr = jQuery.ajax({
          type: 'POST',
          url: 'https://developer.bazaarvoice.com/data/submitreview.json',
          data: {
            rating: 5,
            title: 'This is an example submission',
            fp: '0400mTR4Z7+BQcwNf94lis1ztli…'
          },
          success: function () {…}
        })
String method

When passing submission data as a string, you must encode the values yourself. Learn more about encodeURIComponent().

var title = encodeURIComponent('This is an example submission')
var blackBoxString = encodeURIComponent('0400mTR4Z7+BQcwNf94lis1ztli…')

var jqxhr = jQuery.ajax({
type: 'POST',
url: 'https://developer.bazaarvoice.com/data/submitreview.json',
data: 'rating=5&title=' + title + '&fp=' + blackBoxString,
success: function () {…}
})

Appendix

Troubleshooting

If things do not appear to be working, you can use the loader configuration trace_handler parameter to troubleshoot. This will provide output and status messages to your callback function.

window.IGLOO.trace_handler = function(message) {
  console.log(message)
}

Server integration

iovation can use resources requested from both your domain (1st party) and iovation's domain (3rd party). Including scripts from both of these domains allows iovation to:

  • 1st party - Collect device information for users whose browsers are configured to disable
    3rd party JavaScript, or that block the iovation domain.
  • 3rd party - Share fraud history for devices and accounts across iovation subscribers.

Loading the 1st party resources will require you to set up reverse proxy as described below.

🚧

The server integration is optional. You should consider implementing the server side integration if you are concerned about script blockers rejecting resources loaded from iovation.

Configuring 1st party resource retrieval

You will host iovation's JavaScript loader, which creates script tags requesting both their 3rd party and 1st party JavaScript. The 1st party resources will be requested from your domain with a path of /iojs/. For example:

<script src="https://yourdomain.example.com/iojs/.."></script>

You will need to set up a reverse proxy that forwards any request with the path /iojs/ to iovation. Your proxy should use the following configuration values:

Location/iojs/
Proxy hosthttps://first.iovation.com/*

The /iojs/ path segment is included so that you can identify which requests to proxy. It should not be included in the proxied request path. This is demontrated in the table below:

1st party request URLhttps://yourdomain.example.com/iojs/path/to/iovation/resource
Proxied request URLhttps://first.iovation.com/path/to/iovation/resource

Proxy guidelines

Your proxy to iovation must meet the following guidelines:

  • Don't forward requests to the URL directly to iovation through a redirect, because those requests can be blocked.
  • Don't create a special sub-domain. This can be just as easily blocked as iovation's domain.
  • Don't cache the results from iovation. The resources loaded by iovation are dynamic in nature and may change with each device.
  • Don't forward the request to iovation in way that drops the headers.

Doing any of the above will break the fraud recognition process.

Proxy examples

The following simplified examples demonstrate how to configure a reverse proxy using several popular servers:

  • NGINX
  • Apache
  • Node
Add the following lines to the server section in the Nginx configuration file (default.conf). 
You must set the location to `/iojs/`.

server {
  ... other configuration entries ...
  location /iojs/ {
  proxy_pass https://first.iovation.com/;
    }
     ...
 }  
1.Enable the following modules in the Apache configuration module (httpd.conf):

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so  

2.Add the following lines, in the main configuration or VirtualHost directive:

SSLProxyEngine  On
ProxyPass /iojs/ https://first.iovation.com/   

3.Save the configuration file and restart Apache.
Node doesn't offer native support for proxying, but there are several modules available from the community. 
The following example uses [nodejitsu/node-http-proxy](https://github.com/http-party/node-http-proxy).

const http = require('http');
const httpProxy = require('http-proxy');

const proxy = httpProxy.createProxyServer({
  target: 'https://first.iovation.com/'
});

const server = http.createServer(function (req, res) {
  // Match '/iojs/'
  const pattern = /\/iojs\//g;
  // Proxy any request that includes '/iojs/'
  if (req.url.search(pattern) !== -1) {
    // Remove '/iojs/' from request path
    req.url = req.url.replace(pattern, '/');
    proxy.web(req, res, {});
  }
  else {
    // Handle your resources
  }
});  

Your device fingerprint

iovation is implemented on this page so you can see an example of a black box string. The string below is the fingerprint for your device

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