Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop people having my website loaded on multiple tabs

People also ask

How do I stop websites opening in multiple tabs?

You cannot (and should not) do that. User can always just open use another browser or another computer to open another view onto the web site. So, basically you cannot ever prevent this. Your web-site should be able to handle multiple tabs viewing the same state.

How do I stop multiple logins on the same browser on different tabs?

Solution 1 While login in page load check the Session["UserName"] value.. if already logged in the some user in the browser.. then redirect default page... if (Session["LoginUserName"] != null) { //redirect to default page.. like Homepage.. }

How do you prevent user from opening the same URL in multiple tabs in the same browser in react JS?

There is nothing you can do to prevent a user from opening multiple tabs and opening the same url in every tab. You could store a cookie in localStorage to see if they opened another tab or not, but that won't work for different browsers or incognito mode.

Can a website see how many tabs are open?

Modern websites use multiple "event listeners" and can detect every move the user is executing. So, if a user switches the tab or hovers over to another tab, it can gather the data and see whether the user stayed on the web page or not. A website can detect this anomaly by using cookies and IDs.


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 detection
function 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.


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.


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:

  • Way around ASP.NET session being shared across multiple tab windows
  • Kiranvj's answer

I know this post is pretty old, but in case it helps anybody, I recently looked into basically doing the same thing using localStorage and sessionStorage.

Similar Anthony's answer, it sets an interval to make sure the originating tab keeps the entry fresh, so that if the browser crashes or somehow closes without calling the unload event (included in the comments but not part of the code for testing purposes), then there would just be a short delay before the application would run properly in a new browser window.

Obviously, you would change the "tab is good", "tab is bad" conditions to do whatever logic you want.

Oh, and also, the createGUID method is just a utility to make the session identifier unique... it is from this answer to a previous question (wanted to make sure I wasn't taking credit for that).

https://jsfiddle.net/yex8k2ts/30/

let localStorageTimeout = 15 * 1000; // 15,000 milliseconds = 15 seconds.
let localStorageResetInterval = 10 * 1000; // 10,000 milliseconds = 10 seconds.
let localStorageTabKey = 'test-application-browser-tab';
let sessionStorageGuidKey = 'browser-tab-guid';

function createGUID() {
  let guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    /*eslint-disable*/
    let r = Math.random() * 16 | 0,
      v = c == 'x' ? r : (r & 0x3 | 0x8);
    /*eslint-enable*/
    return v.toString(16);
  });

  return guid;
}

/**
 * Compare our tab identifier associated with this session (particular tab)
 * with that of one that is in localStorage (the active one for this browser).
 * This browser tab is good if any of the following are true:
 * 1.  There is no localStorage Guid yet (first browser tab).
 * 2.  The localStorage Guid matches the session Guid.  Same tab, refreshed.
 * 3.  The localStorage timeout period has ended.
 *
 * If our current session is the correct active one, an interval will continue
 * to re-insert the localStorage value with an updated timestamp.
 *
 * Another thing, that should be done (so you can open a tab within 15 seconds of closing it) would be to do the following (or hook onto an existing onunload method):
 *      window.onunload = () => { 
                localStorage.removeItem(localStorageTabKey);
      };
 */
function testTab() {
  let sessionGuid = sessionStorage.getItem(sessionStorageGuidKey) || createGUID();
  let tabObj = JSON.parse(localStorage.getItem(localStorageTabKey)) || null;

    sessionStorage.setItem(sessionStorageGuidKey, sessionGuid);

  // If no or stale tab object, our session is the winner.  If the guid matches, ours is still the winner
  if (tabObj === null || (tabObj.timestamp < new Date().getTime() - localStorageTimeout) || tabObj.guid === sessionGuid) {
    function setTabObj() {
      let newTabObj = {
        guid: sessionGuid,
        timestamp: new Date().getTime()
      };
      localStorage.setItem(localStorageTabKey, JSON.stringify(newTabObj));
    }
    setTabObj();
    setInterval(setTabObj, localStorageResetInterval);
    return true;
  } else {
    // An active tab is already open that does not match our session guid.
    return false;
  }
}

if (testTab()) {
  document.getElementById('result').innerHTML = 'tab is good';
} else {
  document.getElementById('result').innerHTML = 'tab is bad';
}

The same problem (and solution) : https://sites.google.com/site/sarittechworld/track-client-windows

Similar : http://www.codeproject.com/Articles/35859/Detect-and-prevent-multiple-windows-or-tab-usage-i


The best way to solve this is to have one-time session IDs.

Eg, each page contain a session ID, that is valid for one visit, is unique, and random. When clicking any one link, it will use & invalidate the session ID, and the new page will have a new session ID.

This will force the user to always browse in the newest window or tab, and also prevents session stealing over the wire. Any attempt to reuse a old session ID should immediately kill also the active session IDs for that user.

Its also important to store, in the session management system, which pages is accessible from page X. So if page X (with session ID abc) contains links to page 1, 2 and 3, any attempt to visit page 4 with session ID abc, will fail and also kill the session.

This will force the user to always have one single session track, and always follow the logic on the site. Any attempt to go forward, back, using history or log entires, or opening multiple windows or tabs, will fail and logout the user in all windows, tabs and devices.

All this can be completely implemented on server-side, without any client-side logic.