Back to top

Session continuation

Setting up a continuation point


The power of Surfly co-browsing lays in its proxy approach. It is through our proxy that data is transferred from the original website to the Surfly session and is synchronized to all the participants. This is done seamlessly, but in some cases an extra implementation might be needed: session continuation. This is optional, but in doing so, you make sure that the necessary info is transferred from the user’s current browser session to the co-browsing session. For example: if your user has filled up their shopping cart, you would want them to keep the contents of the cart when a Surfly session is initiated. In some cases you would need session continuation to make this possible.


By default we apply state transfer, this includes the transfer of all non-HTTP-only cookies. By default we assume that the scope is path=/;domain=.example.com. Furthermore, we also transfer browser storage and form fields. Meaning that in most cases, the transition from the website to a co-browsing session will be seamless.


The state transfer becomes a bit more tricky when you want to transfer HTTP-only cookies. These cookies might contain essential information for the browser session to work properly, but due to the HTTP-only flag, Surfly can’t access them by default and therefore we can’t read the full request. To make sure that this information is available inside the co-browse session, it is important to set up a continuation point.


Transferring the state


When the user initiates a co-browsing session, a co-browsing view is opened on top of the original web page, and within this new window (which is called an iframe) the co-browsing session starts. The co-browsing session is a proxied version of the original web page, and therefore the browser recognizes it as a different web session. For your users, it will almost have the same effect as when you refresh the page: the data that was stored in their web session seems to disappear.


Example: Shopping Cart

A user is browsing through a shopping website. While they navigate through the website, pieces of data are stored in different ways, like in cookies for instance. In one of these cookies, the contents of the user’s shopping cart is saved. The user then struggles filling in the payment form, and they seek help from a support agent. They start a co-browsing session, and an iframe containing the co-browsing session opens on top of the original website. The user doesn’t see much of a difference, except for the second cursor on the screen that belongs to the agent. But then they proceed to the checkout page and all of a sudden the shopping cart is empty. Surfly wasn’t able to read the data in the cookie, because it has an HTTP-only flag, so the contents of the shopping cart was not transferred to the co-browsing session.


Cookies


A user’s browser communicates with your website’s server through HTTP: a request/response protocol. The browser sends a request each time your users navigate on your website, and the server responds with data that the browser then translates into something the user can understand.


HTTP itself is stateless: it does not store any data. So for your browser to actually save a certain state (to remember the contents of your shopping cart for instance), different solutions are needed. Cookies are one of them, and they allow the server to store data on the client’s side, in the browser. This can be stored on memory or on disk. Once a cookie is set, by default it will be send with each next request that you make to the same exact host.


The cookies are added to the request as one of the request headers and they contain specific variables: name, value, domain, path and expiration date. It might also carry a flag: HTTP and/or secure. When a browser makes a request to the website’s server, the server reads the values of the cookie in the request, interprets it and adjusts its behaviour accordingly.


Example: logging in

When you log in to a website, Facebook for instance, your logged-in state is saved in a cookie. With each action that you perform on Facebook, an HTTP request is send to the Facebook servers, so your login cookie is send each time. If this weren’t to happen, you would be logged out of Facebook immediately when you navigate to a different page.


Browser storage


Next, there’s also browser storage, which consists out of sessionStorage (erased when you close the entire browser) and localStorage (persistent). What is stored are also bunches of variables, which can be accessed through Javascript. It’s similar to a cookie, but in contrary, it is not send with HTTP requests. The advantage of using browser storage is that you can store bigger chunks of data.


Transferring HTTP-only cookies

Unlike non-HTTP-only cookies and browser storage, cookies with an HTTP-only flag can’t be accessed through Javascript. So why apply this flag? It’s a security measure. If you’re running scripts on your website that you don’t trust (from third parties for instance), it’s good to add this to your cookies. It ensures that cookies with an HTTP-only flag are only accessible on your server.


This does mean that, if you want to ensure a seamless co-browsing experience and transfer the contents of a shopping cart or the logged in state of your users to the co-browsing session, an extra measure has to be implemented next to soft session continuation to ensure the transfer of all cookies: a continuation point.


To summarize, the difference between state transfer and session continuation is:


State Transfer Session Continuation
sessionStorage checkmark checkmark
localStorage checkmark checkmark
Form fields checkmark checkmark
non-HTTP-only cookies checkmark checkmark
HTTP-only cookies x-icon checkmark

Session continuation setup


Since HTTP-only cookies are only accessible on your own servers, Surfly has to act like your server to be able to receive the cookies in order to ensure session continuation. You can do this by setting up a continuation point. This is a special section on your website, yourwebsite.com/surfly_cookie_transfer/, which proxies requests to the Surfly server.


When set up correctly and you start a co-browsing session on your website, automatically a new request is created and send to yourwebsite.com/surfly_cookie_transfer/. This request will contain all the cookies. The Surfly server can then grab the cookies, including the HTTP-only cookies. This way, Surfly can securely include HTTP-only cookies within the co-browsing session, therefore ensuring a seamless co-browsing experience.



Setting up a continuation point usually only requires a small adjustment to your load balancer. The setup entails that you grant the Surfly server access to this specific path only. When a Surfly session is started, your server needs to forward all HTTP requests for the path /surfly_cookie_transfer/* to the Surfly server. If you have implemented Surfly on more than just one domain, if your website sets cookies on multiple subdomains, or if a website is served over HTTPS and HTTP, you may need to setup multiple continuation points. For example, if you store a user authentication token on example.com, but also keep shopping cart cookies on cart.example.com. You can find example configurations for popular load balancers below. Note that there might be slight differences, depending on versions.


Nginx


Add these lines in your config file:


location /surfly_cookie_transfer/ {
    proxy_pass https://surfly.com;
    proxy_redirect off;
    proxy_set_header X-Continuation-Origin https://example.com;
    proxy_set_header X-Widget-Key **Widget key here**;
}

Haproxy


frontend example-com-https
  acl surfly_session_continuation hdr(host) -i example.com path_beg /surfly_cookie_transfer/
  use_backend surfly_continuation_point_https if surfly_session_continuation
  ...your custom configuration here...

backend surfly_continuation_point_https
   https://example.com
   http-request set-header X-Widget-Key **Widget key here**
   http-request set-header Host surfly.com
   server surfly surfly.com:443 ssl

Apache


Make sure you have mod_ssl, mod_proxy, mod_proxy_http, and mod_headers modules installed and loaded, see this tutorial for details):


SSLProxyEngine On

<Location "/surfly_cookie_transfer/">
   RequestHeader set X-Continuation-Origin "https://example.com"
   RequestHeader set X-Widget-Key "**Widget key here**"
   ProxyPass "https://surfly.com/surfly_cookie_transfer/"
</Location>

Custom continuation point


If you cannot make use of the configs above, you can implement the continuation point by other means (for example, in a server-side script). Here is what a continuation point is expected to do:


  • It should pass all HTTP(S) requests which paths start with /surfly_cookie_transfer/ to the Surfly server.

  • Host header must contain the host of the Surfly server (e.g. surfly.com) if you’re proxying to our main production server

  • It must add two additional request headers: X-Widget-Key and X-Continuation-Origin:

    • X-Widget-Key must contain your widget key
    • X-Continuation-Origin must contain an Origin of your website. That is, a protocol scheme followed by domain name and a port in case it is non-standard. For example, a continuation point at https://example.com/surfly_cookie_transfer/ should set X-Continuation-Origin to "https://example.com“. Note that the protocol scheme matters in this case (”http://example.com" and "https://example.com" are different origins).

Verifying the continuation point


Once you’ve set up the continuation point, you can check the session continuation status by typing in your domain, and adding /surfly_cookie_transfer/ to the end. For example, https://example.com/surfly_cookie_transfer/. That page will execute a quick check, and report if there are some problems detected. If any of the boxes are red, it means that your continuation point is not set up correctly. Click the “?” of the respective box for instructions on how to adjust this. For instance, you might find that the bottom box will light up red. This has to do with the company domain settings.

continuation-point-red-check


Updating your Surfly settings


The next step is to update the following options:


  • add all continuation points to the cookie_transfer_urls list

  • cookie_transfer_proxying must be set to to true

  • set cookie_transfer_scopes. Within the cookie transfer scopes, you need to specify all the cookies you want to transfer. So this also includes the non-httpOnly cookies.


Note: If you want to only change the cookie scopes but you don’t require a continuation point, you can also only update the cookie_transfer_scopes option. In this case you must not set cookie_transfer_urls or cookie_transfer_proxying.


Finally, your session continuation settings might look something like this:

{
    cookie_transfer_enabled: true,
    cookie_transfer_proxying: true,
    cookie_transfer_urls: ["https://www.example.com/surfly_cookie_transfer/", "https://cart.example.com/surfly_cookie_transfer/", "https://www.example.io/surfly_cookie_transfer/"],
    cookie_transfer_scopes: [
      {"path": "/", "domain": ".example.com", "name": "cookie1", "httponly": true},
      {"path": "/", "domain": ".cart.example.com", "name": "cookie2", "httponly": true},
      {"path": "/", "domain": ".yourdomain.io", "name": "cookie3", "httponly": true},
      {"path": "/", "domain": "yourdomain.io", "name": "cookie4", "httponly": false}  // a host-only cookie, note the domain without a leading dot
    ]
};

Note: you can also update these settings in the Surfly dashboard


When you check your continuation point status page again, it should look like this:


session-continuation-page

Generated by aglio on 14 Dec 2018