Stop people having my website loaded on multiple tabs Stop people having my website loaded on multiple tabs javascript javascript

Stop people having my website loaded on multiple tabs


I've created a simple solution for this. The master page layout creates a tab GUID and stores it in sessionStorage area of the tab. The using an event listener on the storage area I write the tab GUID to the sites localStorage area. The listener then compares the tabs GUID to the one written to site storage and if they differ then it knows more than one tab is open.

So if I have three tabs A,B,C then click something in tab C, tab A and B detect another tab is open and warn user of this. I haven't yet got to fixing it so the last tab used get's notification, work in progress.

Here's the JS I have in master page, plus in the login page I have a localStorage.Clear to clear last tab from previous session.

    // multi tab detectionfunction register_tab_GUID() {    // detect local storage available    if (typeof (Storage) !== "undefined") {        // get (set if not) tab GUID and store in tab session        if (sessionStorage["tabGUID"] == null) sessionStorage["tabGUID"] = tab_GUID();        var guid = sessionStorage["tabGUID"];        // add eventlistener to local storage        window.addEventListener("storage", storage_Handler, false);        // set tab GUID in local storage        localStorage["tabGUID"] = guid;    }}function storage_Handler(e) {    // if tabGUID does not match then more than one tab and GUID    if (e.key == 'tabGUID') {        if (e.oldValue != e.newValue) tab_Warning();    }}function tab_GUID() {    function s4() {        return Math.floor((1 + Math.random()) * 0x10000)          .toString(16)          .substring(1);    }    return s4() + s4() + '-' + s4() + '-' + s4() + '-' +      s4() + '-' + s4() + s4() + s4();}function tab_Warning() {    alert("Another tab is open!");}

Note: It's IE9+

Hope this helps.


EDIT2:

It's the exact thing which is mentioned at this answer, You need 2 IDs:

  1. One random one
  2. One consistent one (this will be our SSID actually, since you limit tabs of a single browser, it's better to get generated form browser's unique parameters)

You can generate consistent one from browser's user-agent or get it from server-side. store both of them server-side.
Store the random one in window.name property which is tab-specific.
Send a heartbeat every 1~2 seconds to your server containing both consistent ID and random one. if server fails to receive the heartbeat, it cleans up database and de-register dead clients.
on every browser's request, check window.name for the value. if it were missing, check with the server-side whether if the previous tab is closed or not (cleaned from database).

If yes, generate a new pair for client if no, reject them.


Two suggestions on top of my mind:
  1. Server-side (better): provide all your clients, a user name and password. request them on their first visit of your site to enter with their credentials. then on every other request, check for whether user with said credentials is already logged in or not.
  Client *         |         |      Server ---> Check whether                  Already logged                     or not?                  ______________                   |          |                  yes         no                   |          |                 permit     reject                  them       them
  1. Client-side: If you really need a strong check of this, use evercookie to store an already-logged-in cookie on client's machine.

Side-note: Do know that every attempt in client side is not secure at all! client-side should help server-side, it shouldn't be used as the one and only source of security. even evercookies can be deleted so, give my first suggestion a go.


**EDIT:**

Evercookie is really doing a good job at storing most secure zombie cookies ever but since the library itself is a little bit heavy for browsers (storing a cookie takes more than 100ms each time) it's not really recommended for using in real-world web app.

use these instead if you went with server-side solution:


UPDATE - 2020

Client side implementation:

We can make use of Broadcast Channel API which allows communication across browsing contexts (windows, tabs, frames or iframes) provided both contexts are from same origin.

A simple implementation to detect 2nd tab loading the website from the 1st tab:

    //in entry point of your app (index.js)        const channel = new BroadcastChannel('tab');    channel.postMessage('another-tab');    // note that listener is added after posting the message    channel.addEventListener('message', (msg) => {      if (msg === 'another-tab') {        // message received from 2nd tab        alert('Cannot open multiple instances');      }    });

This doesn't use localStorage or cookies and it even works if 1st tab is offline and 2nd tab is being loaded.

Note: This is not supported in Safari & IE11 yet :(

Take a note on its browser compatibility.

However, there's a polyfill available that does the job.