Warn the user before session timeout

前端 未结 7 2308
感动是毒
感动是毒 2020-12-09 18:08

I have a web application implemented in Spring MVC, JSP.
Default session timeout is defined in web.xml is 30 min.

if use

相关标签:
7条回答
  • 2020-12-09 18:37

    In order to notify the user about the timeouts on the frontend, you need to pass this information from your backend. To accomplish this, I used the info in https://www.javaworld.com/article/2073234/tracking-session-expiration-in-browser.html as a baseline.

    In each Response method in your Controller you need to include cookies containing the session timeout time, as well as the current server time. Since it sounds like you've already set the session-timeout in your web.xml, you can add the cookies to your response with something similar to:

    @RequestMapping(value="/example", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public ResponseEntity<Object> getExample(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
         addTimeoutCookies(servletRequest, servletResponse);
    
         //Do actual actions
    
         return new ResponseEntity<Object>(HttpStatus.OK)
    }
    
    private void addTimeoutCookies(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
    
        long currTime = System.currentTimeMillis();
        long expiryTime = currTime + servletRequest.getSession().getMaxInactiveInterval() * 1000;
    
        Cookie serverTimeCookie = new Cookie("serverTime", "" + currTime);
        serverTimeCookie.setPath("/");
        servletResponse.addCookie(serverTimeCookie);
    
        Cookie expiryCookie = new Cookie("sessionExpiry", "" + expiryTime);
        expiryCookie.setPath("/");
        servletResponse.addCookie(expiryCookie);
    }
    

    Then, on the frontend, you need to retrieve the values of these cookies and compare them against the client current time to determine when to notify the user about the upcoming session timeout. Here's a simple code block to do this, based on the other answers here and the article at the link:

    var currTimeCookieName = 'serverTime';
    var expireTimeCookieName = 'sessionExpiry';
    var offset;
    var warningTime = 5 * 60 * 1000;
    var timeoutWarningMessage = 'Your session is going to be end by 5 min, Please click OK to continue';
    
    function getCookie(name)
    {
        var name = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0; i<ca.length; i++)
        {
            var c = ca[i].trim();
            if (c.indexOf(name)==0) return c.substring(name.length,c.length);
        }
        return "";
    }
    
    var serverTime = getCookie(currTimeCookieName);
    serverTime = serverTime==null ? null : Math.abs(serverTime);
    var offset = (new Date()).getTime() - serverTime;
    
    function getTimeToWarning() {
        var expireTime = getCookie(expireTimeCookieName);
        return expireTime + offset - currTime - warningTime;
    }
    
    function checkForTimeout() {
        var timeUntilWarning = getTimeToWarning();
    
        setTimeout(function(){
            if (getTimeToWarning() > 0) {
                checkForTimeout();
            } else {
    
                if(confirm(timeoutWarningMessage)) {
                    //TODO do a backend call or other action to extend the session here
    
                    setTimeout(function() {
                        checkForTimeout();
                    }, 1 * 60 * 1000);
                }
            }
        }, timeUntilWarning);
    }
    
    checkForTimeout();
    
    0 讨论(0)
  • 2020-12-09 18:39

    You can use like follows: I am using that in a jsp page like header.jsp. It works fine for me. I am using spring, jsp and jquery.

    javascript:

    <code>
    <script type="text/javascript">
        //var recall = true;
        function loadDialog() { 
                var sessionAlive = ${pageContext.session.maxInactiveInterval};          
                var notifyBefore = 30; // Give client 15 seconds to choose.
                setTimeout(function() {       
                    $(function() {
                        $( "#dialog" ).dialog({
                            autoOpen: true,
                            maxWidth:400,
                            maxHeight: 200,
                            width: 400,
                            height: 200,
                            modal: true,
                            open: function(event, ui) {
                                setTimeout(function(){
                                    $('#dialog').dialog('close'); 
                                }, notifyBefore * 1000);
                            },
                            buttons: {
                            "Yes": function() {  
                                 $.get("/about", function(data,status){
                                   // alert("Data: " + data + "\nStatus: " + status);
                                  });                             
                                $('#dialog').dialog("close");
                                loadDialog();
                            },
                            "No": function() {  
                                $('#dialog').dialog("close");
                            }
                           },
                           close: function() {}
                        });
                      });
                }, (sessionAlive - notifyBefore) * 1000);
        };
    
        loadDialog(); 
    </script>
    

    HTML Div:

    <div id="dialog" title="Session Timeout Info" style="display:none">
      <p>
        Your session will be timeout within 30 seconds. Do you want to continue session?  
      </p>
    </div> 
    </code>
    
    0 讨论(0)
  • 2020-12-09 18:46

    You can use the following plugin - Jtimeout jquery plugin Works perfectly and is configurable too. The doc is pretty clear

    0 讨论(0)
  • 2020-12-09 18:47

    You could send a cookie with the remaining time (in milliseconds) on every request. Then you can use setTimeout as suggested but test the value again when the timeout-function is executed. If the value has changed you can reset the timeout. Since the cookie is set for the whole domain it will always be correct even for ajax or other tabs.

    var cookieName = 'sessionMsg';
    var message = 'Your session is going to be end by 5 min, Please click OK to continue';
    
    function getCookie(name)
    {
        var name = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0; i<ca.length; i++)
        {
            var c = ca[i].trim();
            if (c.indexOf(name)==0) return c.substring(name.length,c.length);
        }
        return "";
    }
    
    function setSessionPrompt() {
        var timeout = getCookie(cookieName) - new Date().getTime();
        setTimeout(function(){
            if (new Date().getTime() < getCookie(cookieName)) {
                setSessionPrompt();
            } else {
                if(confirm(message)) {
                    // do your action here
                }
            }
        }, timeout);
    }
    
    setSessionPrompt();
    
    0 讨论(0)
  • 2020-12-09 18:48

    Try this code. Hopefully it will solve your problem. Thanks

    var cookieName = 'sessionMsg';
    var message = 'Your session is going to be end by 5 min, Please click OK to continue';
    
    function getCookie(name)
    {
        var name = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0; i<ca.length; i++)
        {
            var c = ca[i].trim();
            if (c.indexOf(name)==0) return c.substring(name.length,c.length);
        }
        return "";
    }
    
    function setSessionPrompt() {
        var timeout = getCookie(cookieName) - new Date().getTime();
        setTimeout(function(){
            if (new Date().getTime() < getCookie(cookieName)) {
                setSessionPrompt();
            } else {
                if(confirm(message)) {
                    // do your action here
                }
            }
        }, timeout);
    }
    
    setSessionPrompt();
    
    0 讨论(0)
  • 2020-12-09 18:50

    You should use WebSockets to send data from the Web Application to clients browser.

    1) calculate the session timeouts at server side. 2) Websocket will send the message about session time out message.

    0 讨论(0)
提交回复
热议问题