我们的应用程序在30分钟后注销并被重定向到登录页面,我正在web中指定会话超时。xml并使用requestProcessor进行重定向。我想向用户显示一条消息,说明一旦会话过期,您的会话已过期,我该如何做到这一点。自动注销?我想在页面上提示错误消息"会话超时,请再次登录"。那么我怎么能检测到会话超时?任何方法都会自动触发吗?

有帮助吗?

解决方案

创建一个活动检查器,每分钟检查是否发生了任何用户活动(mouseclick,keypress),并向服务器端执行心跳,以在用户处于活动状态时保持会话活动,而在用户不处于活动如果30分钟内没有活动(或者服务器端设置了任何默认会话超时),则执行重定向。

这里有一个很少帮助的开球例子 jQuery的 绑定点击和按键事件并触发ajax请求.

<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
    $(document).ready(function() {
        $.active = false;
        $('body').bind('click keypress', function() { $.active = true; });
        checkActivity(1800000, 60000, 0); // timeout = 30 minutes, interval = 1 minute.
    });

    function checkActivity(timeout, interval, elapsed) {
        if ($.active) {
            elapsed = 0;
            $.active = false;
            $.get('heartbeat');
        }
        if (elapsed < timeout) {
            elapsed += interval;
            setTimeout(function() {
                checkActivity(timeout, interval, elapsed);
            }, interval);
        } else {
            window.location = 'http://example.com/expired'; // Redirect to "session expired" page.
        }
    }
</script>

创建一个 Servlet 它倾听 /heartbeat 基本上只做以下事情:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    request.getSession();
}

让会议保持活力。

当您将登录用户存储在会话中时,每当会话过期时,它都会"自动"注销。所以你不需要手动注销用户。

其他提示

创建一个实现生成的侦听器类,并在web.xml中定义它

这将在任何会话被销毁时通知您。使用HttpSessionListener方法。

在此处查看一个完整的示例:

http://www.mkyong。com / servlet / a-simple-httpsessionListener-examptive-sessions-counter /

它可能是简单的servlet,没有完美的客户端逻辑,不可能进行Spring-MVC或Spring-Security自动注销。
考虑应用程序将具有两种类型的请求

  • ajax和
  • 表格提交/页重载

自动注销需要非常计算的逻辑。介绍我的自动突发功能实现,下面

优点。


1.不使用额外的呼叫/请求来实现这一目标。考虑到超过10k有效的用户和额外的呼叫来实现自动注销,会影响性能影响。
2.使用标签的一行配置。

3.即使用户打开多个标签或多个窗口,也可以完美地工作。
4.它在30秒的会话无效之前将您充满了解您,因此如果您填充了表单而未提交,则可以保持会话活动(通过单击扩展会话)。因此用户不太可能松开未撤下的数据。

用法


1。包括如下所示的所需JSP页面中的自动注销脚本。

    ....
    </body>
    <jsp:include page="../template/autologout-script.jsp"></jsp:include>
</html>
.

2。创建JSP页面,AutogOut-Script.jsp并添加以下代码。 注意:不需要编辑/配置

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<script>
$(document).ready(function()
{
    var timeOutTimeInSeconds = ${ timeOutTimeInSeconds }; 
    var showTimerTimeInSeconds= ${ showTimerTimeInSeconds };

    var sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
    var timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
    var badgeTimerId;
    window.localStorage.setItem("AjaxRequestFired", new Date());

    function redirectToLoginPage(){
        //location.href =  '<c:url value="/" />'+'${loginPageUrl}';
        window.location.reload();
    }

    $(document).ajaxComplete(function () {
        resetTimer();
    });

    $(window).bind('storage', function (e) {
         if(e.originalEvent.key == "AjaxRequestFired"){
             console.log("Request sent from another tab, hence resetting timer")
             resetTimer();
         }
    });

    function resetTimer()
    {
        showTimerTimeInSeconds= ${ showTimerTimeInSeconds };

        console.log("timeOutTimeInSeconds : "+timeOutTimeInSeconds)
        window.localStorage.setItem("AjaxRequestFired", new Date());

        window.clearInterval(sessionCheckIntervalId);
        sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);

        window.clearInterval(timerDisplayIntervalId);
        timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);

        hideTimer();
    }

    function showTimer()
    {
        $('#sessionTimeRemaining').show();
        $('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
        window.clearInterval(timerDisplayIntervalId);
        badgeTimerId = setInterval(function(){
            $('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
        }, 1000);
    }

    function hideTimer()
    {
        window.clearInterval(badgeTimerId);
        $('#sessionTimeRemaining').hide();
    }
});
</script>
.

3。配置会话属性以配置超时设置 注意:在会话创建后配置此内容。您可以根据您的要求实现HttpsessionListener会话创建的方法并设置以下配置。

session.setMaxInactiveInterval(300);

session.setAttribute("timeOutTimeInSeconds", 300);
session.setAttribute("showTimerTimeInSeconds", 30);

.

4。添加以下HTML以显示计时器。
注意:如果您擅长CSS,它可以移动到“自动脚本模板”页面。因此,您可以避免在每个页面中添加此页面。
包括引导或添加自定义CSS。

<span class="badge badge-primary" title="click to keep session alive" id="sessionTimeRemaining" 
    onclick="ajaxSessionRefresh()" style="display:none;">
    <i class="badge badge-danger" id="sessionTimeRemainingBadge" style="float:left">30</i>
     &nbsp; 
     <small>Refresh</small>
     <i class="glyphicon glyphicon-refresh"></i>
</span>
.

这完全是关于一个简单的自动注销实现。 您可以从我的github存储库下载工作示例 使用简单servlet示例
使用spring-security java配置excutize
自动解决spring-security xml配置examply excext

逻辑解释


案例1:页面加载
这里逻辑很简单,页面加载间隔Equlas的计时器到MaxInactiveInterval。超时重定向到登录页面。
案例2:保持跟踪Ajax调用
现在考虑ajax请求,您可以使用.ajaxstart()或.ajaxcomplete()jQuery的回调,以便如果解雇任何AJAX请求,则可以重置间隔。
案例3:跟踪多标签/窗口活动
Intertab通信是为了同步每个选项卡的状态。在更改事件时使用localstorage。

限制/改进所需
1.如果最大允许的会话是一个,如果从另一个系统中拍摄会话,则Ajax请求将失败。需要处理以重定向到登录页面。
2.使用ajaxstart()而不是ajaxcomplete()在服务器和浏览器之间精确同步iDletime值。

要求
1. jquery

电流实现的替代方案比较


1. <强>在HTTP响应中设置刷新标题
(不适用于Ajax请求)

response.setHeader("Refresh", "60; URL=login.jsp");
.

  1. 在html 中设置元刷新标记(不适用于ajax请求)
  2. <meta http-equiv="refresh" content="60; url=login.jsp">
    
    .
    1. 配置活动检查 通过重复的AJAX请求保持活动。追踪空闲时间并在超时后进行注销请求。
      毫无疑问,这是一个很好的逻辑。但我想只是墨水我的观察。
      • 性能影响如果每分钟进行2个请求以保持会话活动和50k活跃的用户。每分钟100K请求。
      • Intertab通信如果打开两个选项卡,则一个选项卡正在接收活动,但其他选项卡未接收活动,即表示其他选项卡中的活动触发注销请求和无效会话。 (但可以处理)
      • 力注销方法它是一个客户端在服务器上占主导地位,使其无效。

如果您正在使用servlet会话,则可以检查jsp / servlet是否返回的会话是新的,使用iSnew()方法是新的。如果是,则用户的会话已过期,您可以显示相关消息。

在JSP中包含JavaScript实用程序函数,每31分钟为服务器Ping服务器。 上面提到的实用程序函数应使用SetTimeOut()JS在内部函数。

setTimeout ( "checkServerSession()",  /* intervalInMilliSeconds */ 31000);
.

注意

checkserversession()

是一个常规的js函数,可以闪光HTTP请求。如果请求是成功的会话,则存在于向用户显示提示。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top