# Paywall

Iteras has a simple Javascript API available for implementing a paywall on your own site.

Under the hood, the API works the way that visitors are denied access unless they have a pass cookie called "iteraspass" authorizing them. This cookie is set in the user's browser on your domain, either through an ordering flow or by the paywall login iframe upon successful login. It is usually valid for an extended period of time.

This design minimizes the coupling between your system and Iteras. Visitors do not depend on access to an Iteras server to view content besides the initial login, improving fault tolerance and response time.

The pass cookie must be regenerated from time to time by Iteras. If the regeneration succeeds, the user can keep on accessing the content, if it fails because the user no longer has access, the cookie is deleted so the user is denied access. The cookie regeneration is done automatically by the Iteras.wall function that you use to check for access.

To get started, you need to add a paywall inside Iteras and configure its settings there. This gives you a paywall id for use in the API.

There are a couple of things you then need to prepare. When visitors are not logged in to the paywall, they need to see an explanation that paywall access is required, a strong call to action for people who have not signed up yet, e.g. with a link to the the ordering iframe, and then some means of logging in. That could either the paywall login iframe or a link to a page with it.

# Basic paywall setup with redirects

The most basic paywall setup is using redirects to guide visitors through the flow.

To do this, you need to setup a landing page for people who are not logged in. As mentioned above, you’d usually include an explanation that paywall access is required, a strong call to action for people who have not signed up yet and some means of logging in for those who have already signed up.

Say the path to your landing page is "/paywall/landing.html", then you call

Iteras.wall({ paywallid: "XXXXXX", redirect: "/paywall/landing.html" })

on all pages you want paywalled. This call checks that a cookie with the right paywall id exists, if not it redirects to the URL given by "redirect". In case you need to check for a pass to either of a number of paywall ids, put in a list, like this

Iteras.wall({ paywallid: ["XXXXXX", "YYYYYYY"], redirect: "/paywall/landing.html" })

The call to Iteras.wall will also automatically regenerate the cookie from time to time by contacting the Iteras server, or delete it if the user no longer has access.

The landing page may get some query/GET parameters starting with "iteras", e.g.

http://www.example.com/paywall/landing.html?iterasnext=...&iterasaccess=...

These are read by the paywall login and ordering iframes, so if you don’t have the iframes embedded directly in the landing page but instead accessible through links, you should append all query parameters starting with "iteras" to those links. Otherwise, visitors will have reduced functionality, e.g. people will not be redirected back to the original page upon logging in.

# Paywall setup with inline handling

In case you need something else than a redirect upon un-authorized access, e.g. in you want to only block of part of the page, you can provide an "unauthorized" callback to the Iteras.wall function instead of the "redirect" parameter, like this

function myPaywallHandler() { ... }
Iteras.wall({ paywallid: "XXXXXX", unauthorized: myPaywallHandler })

In your callback function, as mentioned above you then need to explain to the visitor that paywall access is required, provide a strong call to action for people who have not signed up yet and some means of logging in for those who have already signed up, for instance by inserting a box with this information.

Note that the Iteras.wall function may call the handler or return immediately and call the handler later. The latter may happen in case the iteraspass cookie is regenerated (which may take some milliseconds) and it turns out the visitor no longer has access.

This can be inconvenient if you have already checked that the user was logged in. Sometimes the easiest way out is simply a redirect, forcing a page rerender.

If you omit both "redirect" and "unauthorized", nothing will happen in case of an unauthorized visitor, but the code will still check the pass cookie from time to time and delete it if it is no longer valid.

You might also need to determine if the user is signed in:

Iteras.signedIn()  // returns true or false

Or access information contained in the paywall pass cookie:

Iteras.paywallPass()
{
    "paywalls": {
        "XXXXXX": "sub",
        "YYYYYY": "user"
    },
    "expires": Date("2021-01-01T13:37:00.000Z"),
    "customer": "123456",
    "ipaddress": "93.176.69.74"
}

# Logging out of the paywall

To log out from the paywall, call

Iteras.logoutFromWall()

e.g.

<button id="logout">Log out</button>

<script>
 document.getElementById("logout").onclick = function () {
     Iteras.logoutFromWall();
 };
</script>

Upon completing the log out, by default the page will be reloaded. You can redirect to another page by specifying a redirect option, like this

Iteras.logoutFromWall({ redirect: "/some/url" })

You can also specify redirect: null to prevent the reload.

# Access levels

There are currently two access levels in Iteras.

  • Visitors with active subscriptions (on campaigns with digital access) are at the "sub" level.
  • Visitors registered as subscribers but with no active subscriptions are at the "user" level.

It is sometimes useful to give the user-level visitors access to selected areas so you can configure Iteras to hand out paywall passes to them, and then add the "access" parameter to the wall function, like this

Iteras.wall({ paywallid: "XXXXXX", redirect: "/paywall/landing.html", access: "user" })

for user-accessible pages and

Iteras.wall({ paywallid: "XXXXXX", redirect: "/paywall/landing.html", access: "sub" })

for pages for the actual subscribing subscribers.

# IP-based access control

Iteras internally has support for adding an IP access field to subscriptions.

It has the effect that when the paywall login iframe is shown, a request is sent to the server and if the request IP address matches a subscription, the client is automatically logged in as the corresponding subscriber as if the client had submitted the password form. From then on, everything else works as usual.

Note that IP-based access can be more difficult to control as it depends on specific firewall and network settings in the client end, compared to the standard paywall which simply depends on a working browser. Often clients are not well-equipped to analyze network problems - they just want access ASAP.

We have a helpdesk article on diagnosing IP-related problems, but otherwise we cannot really help.

The paywall pass cookie consists of a number of fields separated by | with a signature at the end beginning with /, e.g.

sub|n8fsoupukhv3|2016-01-23T12:35:29Z|31168|123.123.123.123/sha256:596c625c185499e6a4394dbcec8713347ba7d0e67acb1fe3fe876f424f35bfc7

The fields can’t contain | or other characters not allowed in cookies so a simple string split can be used for parsing. The fields are currently:

  • access level - in case of multiple paywall ids, the level for each paywall is separated with a comma in the same order as the paywall ids in the next field
  • paywall id - in case of multiple paywall ids, they are separated with a comma, e.g. XXXXX,YYYYY
  • UTC timestamp for when the pass expires (normally requiring new login)
  • customer number
  • IP address of other end when pass was granted

You can count on the ordering of the fields, but we might add more fields at the end in the future so don’t write code that assumes that the number of fields is fixed.

The signature is everything to the right of the last / in the pass and consists of a signing algorithm identifier followed by : followed by the actual signature. The signing algorithm is run on everything to the left of the /.

"sha256" means HMAC SHA256 with hexadecimal numbers as output (this is a standard algorithm with implementations in many programming environments). The key used for the HMAC is the signing key you can find in the settings inside Iteras.

The signature is not checked in the JS API, but you can check it server-side to ensure that the cookie was actually generated by Iteras.

In case the pass cookie is needed on subdomains, the cookie domain can can be set for the plugin. Remember to configure it before using the Iteras paywall API.

<script src="https://app.iteras.dk/static/api/iteras.js"></script>
<script>Iteras.cookieDomain = ".example.com";</script>

# Server-side check

Note that the Javascript paywall API here as a client-side solution allows sufficiently skilled people to trick the paywall.

If this is a problem, make a server-side check of the pass cookie as described in the previous section and modify the server to prevent content from being sent to people without a valid cookie.

However, as long as it is difficult enough to circumvent the paywall for 99.999% of your target audience - especially on relatively locked-down consumer tablets and phones - it may not be cost-effective to take this extra step.