首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >会话过期/超时后JSP自动重定向

会话过期/超时后JSP自动重定向
EN

Stack Overflow用户
提问于 2010-10-12 22:35:17
回答 4查看 34K关注 0票数 6

有没有办法在没有(用户交互)*的情况下检测会话超时,并将其重定向到某个页面;即,如果在特定持续时间内页面上没有活动,服务器会检测到它并自动将其重定向到其他页面。

通过用户用户交互,我的意思是;有一种方法可以检测会话超时,当用户单击某个东西时,然后一些请求进入服务器,然后服务器检查当前用户会话是否过期。

这里我需要的是我们不通知服务器任何东西(或者我们不执行任何操作),但是当会话过期时,服务器会自动检测到它并执行所需的操作。

谢谢,Raza

EN

Stack Overflow用户

发布于 2019-08-25 08:34:57

要么是简单的servlet,要么是spring-mvc,要么是spring-security如果没有完善的客户端逻辑,自动注销是不可能的。

考虑到应用程序将同时具有这两种类型的请求

  • AJAX和

  • 表单提交/页面重新加载

自动注销需要经过精心计算的逻辑。使用以下代码展示我的autologout功能实现

优势。

  1. 无需额外的调用/请求即可实现此目的。考虑超过10k活动用户和额外呼叫时的性能影响,以实现自动注销。

使用tag的

  1. 单行配置。

即使用户打开多个选项卡或多个窗口,

  1. 也能完美工作。

  1. 它会在会话失效前30秒提示您,因此,如果您已填写表单但未提交,您可以保持会话活动(通过一次单击扩展会话)。因此用户不太可能丢失未保存数据。

用法

JSP1.在所需的页面中包含自动注销脚本,如下所示。

代码语言:javascript
运行
复制
    ....
    </body>
    <jsp:include page="../template/autologout-script.jsp"></jsp:include>
</html>

2.创建一个JSP、autologout-script.jsp并添加以下代码。注意:无需编辑/配置

代码语言:javascript
运行
复制
<%@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 sessionCreated方法,并根据您的需求设置以下配置。

代码语言:javascript
运行
复制
session.setMaxInactiveInterval(300);

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

定时器4.添加下面的以显示定时器。

注意:如果你擅长CSS,可以把它移到autologout-script模板页面。因此,您可以避免在每个页面中添加此内容。

包括bootstrap或添加自定义css。

代码语言:javascript
运行
复制
<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存储库下载工作示例

Autologout using simple servlet example

Autologout using spring-security java configuration example

Autologout using spring-security xml configuration example

逻辑解释

案例1:页面加载

这里的逻辑很简单,在页面加载时将计时器的间隔公式设置为maxInactiveInterval。超时后重定向到登录页面。

案例2:跟踪AJAX调用

现在考虑AJAX请求,您可以使用jquery的.ajaxStart()或.ajaxComplete()回调,以便在触发任何ajax请求时可以重新设置间隔。

案例3:跟踪多选项卡/窗口活动

进行标签间通信以同步每个标签的状态。已在更改事件上使用localStorage。

需要限制/改进

  1. 如果允许的最大会话数为1,则从另一个系统获取会话,AJAX请求将失败。需要进行处理才能重定向到登录页面。
  2. 使用ajaxStart()而不是ajaxComplete()在服务器和浏览器之间精确同步idleTime值。

要求

  1. Jquery

比较了当前实施的替代方案

http响应中的

  1. Setting刷新头。(不适用于AJAX请求)

代码语言:javascript
运行
复制
response.setHeader("Refresh", "60; URL=login.jsp");

HTML中的

  1. Setting元刷新标签(不适用于AJAX请求)

代码语言:javascript
运行
复制
<meta http-equiv="refresh" content="60; url=login.jsp">

  1. Configuring活动检查器通过重复的AJAX请求来保持会话活动。跟踪空闲时间,并在超时后发出注销请求。

毫无疑问,这是一个逻辑简单的好问题。但我只想写下我的观察结果。如果每分钟发出2个请求以保持会话活动和50k活动用户,则

  • Performance会影响。100k requests per minute.
  • Intertab communication如果打开了两个选项卡,其中一个选项卡正在接收活动,但另一个选项卡没有接收活动,则该选项卡会触发注销请求并使会话无效,即使其他选项卡中存在活动也是如此。(但可以通过handled)
  • Force注销方法来使session.

无效,是客户端主导服务器

票数 0
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3915787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档