2

I am developing a enterprise application using spring and struts. But, i'm getting issue on Tab close. how to force user logging out when close the browser tab or open same page on another tab.

i have been try using onbeforeunload but i am getting issue when application running on mobile browser. and i also have seen following sample but No one has clear explanation.

How to kill session when user closed the browser without logout

How to Detect Browser Window /Tab Close Event?

is there any solution to achieve this problem using javascript or from server? Thanks

Aleksandr M
  • 24,264
  • 12
  • 69
  • 143
Ahmad hamid
  • 31
  • 1
  • 3
  • You can check https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload – brk Jul 05 '17 at 03:56
  • The `HttpServletRequest.logout()` method can be used to log the current user out. Typically this means that the `SecurityContextHolder` will be cleared out, the `HttpSession` will be invalidated, etc. – Jay Smith Jul 05 '17 at 03:59
  • @JaySmith yes, but how to log the current user out when close tab browser? – Ahmad hamid Jul 05 '17 at 04:21
  • https://stackoverflow.com/a/3888938/6743203 – Jay Smith Jul 05 '17 at 04:23
  • 1
    IIRC there is no 100% guaranteed way - when the page is refreshed the `onbeforeunload` is also called – Scary Wombat Jul 05 '17 at 04:37
  • What happens when you push the browser to an inactive state or close the tab in your mobile phone? – Aakash Verma Jul 05 '17 at 04:51
  • HTTP is stateless protocol, so there is no way for you to know if other side closed tab, other than just use timeout. – fg78nc Jul 05 '17 at 05:01

4 Answers4

4

Finally I found a solution that worked!

When the user logs in I use sessionStorage to store that a user has been logged in:

sessionStorage.setItem('logged', true)

SessionStorage will hold that property until the tab or the browser closes.

So inside the application, I check if the SessionStorage still holds that property. If not then I logout the user and I redirect him to the login.

if (!sessionStorage.getItem('logged')) {
  localStorage.removeItem('token')
  navigator.sendBeacon('api/logout')
  window.location.replace("/login") //redirect to login
}

For those who wonder what is navigator.sendBeacon you can read here to learn more. Practically I use it because I want the api/logout to be accessed even if the tab closes.

Roland
  • 24,554
  • 4
  • 99
  • 97
  • I'm using an HttpOnly cookie for my token, but I was storing loginInfo in localStorage to allow for browser refresh. Thanks to this solution, I just moved it to sessionStorage and now users are properly logged out when the tab/browser is closed. Time to rewrite a buncha old stuff! – jesse crossley May 27 '21 at 20:09
0

You may start a ajax request by page onload, and get a tracking session id/serial from server.
Later force all of the requests operations to include the tracking session you just gave to the page using the ajax call above.

If user opens up a new tab, the ajax load starts again. and As far as you check the live session tracks in the server with associated user, you may redirect the user to somewhere else or etc.

I don't think you may rely on onbeforeunload, just the same thing you experience.

As others stated, http is stateless, and cookies and requests are only stuffs you can check the state of the user.

At the server, session cookies could be invalidated by session timeout(if we assume user going to brew some coffee, e.g. it closes the page/tab).
And as explained in above solution, if he/she opens a new tab, the new ajax call might block him/her to perform a new login or etc.

I suggest you may find another solution instead of this approach you are trying to get. It's much easier and more senseful to sync the page state with the last opened page. Let the user opens 5 same page, and just sync them all with each other(simplest solution: refresh others when one gets updated)

0

You may have a javascript function and invoke it on "onunload" of body and in that script invoke backend code to invalidate the user session.

0

localStorage can be use to keep idle time for the application with multiple tabs are opened.

    // Check browser support
  if (typeof(Storage) !== "undefined") {
    // Store an item to localStorage
    localStorage.setItem("timeIdle", "0");
    console.log(localStorage.getItem("idleTime"));
    // Retrieve the added item
  } else {
    //display this message if browser does not support localStorage
    console.log("Sorry, your browser does not support Web Storage.");
  }
  function func(){
        $(this).keypress(function(e) {
            localStorage.setItem("timeIdle", "0");
        });
        $(this).click(function(e) {
            localStorage.setItem("timeIdle", "0");
        });
        timerIncrement();
    }
  function timerIncrement() {
        var timeIdle = localStorage.getItem("timeIdle");
        timeIdle = parseInt(timeIdle) + 1;
        if (timeIdle >= 1) {
            logoutCall();
            window.location = window.location.origin+"/riskoffice-ui/Login";
        }
        localStorage.setItem("timeIdle", timeIdle.toString());
  }
 setInterval(func,1800000); //Runs the "func" function every second
Sandeep Jain
  • 1,019
  • 9
  • 13