Grails:处理HTTP会话超时事件

时间:2013-01-09 17:52:44

标签: grails session-timeout http-status-code-401 url-mapping

我正在编写使用Sprint Security进行身份验证的Grails应用程序。我需要向用户显示一条消息,该用户由于不活动而自动注销。

我的应用程序使用AJAX请求和对控制器的直接请求。我注意到,对于AJAX请求,Sprint Security使用代码401返回HTTP响应,并且我已经以这种方式重新定义了默认URL映射:

class UrlMappings {
    static mappings = {
         // ...

         "401" (controller: 'errors', action: 'inactivityLogout')
    }
}

这是inacticityLogout()方法的主体:

def inactivityLogout() {
    log.debug("the user is logged out due to inactivity")
    session.setAttribute('inactivityMessage', "You have been logged out due to inactivity.")
    render(status: 401)
}

然后LoginController检查是否设置了inactivityMessage属性,并在登录页面上显示相应的消息。

问题是这个解决方案适用于AJAX调用,但是当我尝试通过单击应用程序中的直接链接导航到另一个页面时不起作用。在第二种情况下,日志为空,因此不调用方法inactivityLogout

Firebug显示应用程序返回代码302暂时移动,所以我认为这是一个原因。但后来我发现同样的代码也会返回给AJAX调用。所以,现在我不知道AJAX和非AJAX请求之间有什么区别,以及为什么Grails URL映射引擎不处理最后一个请求。

任何想法,我目前的解决方案可能出现什么问题?这个问题能以完全不同的方式解决吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

使用jQuery,这就是我的工作:

$.ajaxSetup({
   statusCode: {
     401: function () {
       $('#ajaxAuthModal').modal('show');
     }
   }
});

我在全局JS文件中有这个,所以我的所有ajax请求都处理401.然后我只显示一个模式告诉用户他们需要再次登录。实现您想要的唯一真正的区别是通过ajax轮询安全资源。这将允许401函数在返回401时触发。

大多数JavaScript库(如jQuery)应具有与$.ajaxSetup()类似的功能。

答案 1 :(得分:1)

  

是的,我们的想法是在没有任何用户互动的情况下显示消息。只是想让用户知道他为什么要从系统中注销。

因此,一旦用户加载页面,就不会与服务器联系。服务器无法将消息“推送”到浏览器。因此,您需要做的是检查是否存在使用JavaScript的活动会话。你很容易用计时器做到这一点。

在main.gsp中将javascript变量设置为${session.maxInactiveInterval}。这将为您提供用户会话的最大长度。只需开始setTimeout( function() { /* code to display to the user here */ }, maxInterval)

请记住重置AJAX调用的时间间隔,因为由于页面没有重新加载,因此不会重置。

作为旁注,URL映射应该仅在非AJAX请求中起作用,因为页面没有被重新加载,因此没有显示页面的内容。您将不得不使用@Gregg用来处理AJAX请求的东西。