Grails:处理HTTP会话超时事件

Grails:处理HTTP会话超时事件,grails,session-timeout,http-status-code-401,url-mapping,Grails,Session Timeout,Http Status Code 401,Url Mapping,我正在编写使用Sprint安全性进行身份验证的Grails应用程序。我需要向由于不活动而自动注销的用户显示一条消息 我的应用程序使用AJAX请求和对控制器的直接请求。我注意到,对于AJAX请求,Sprint Security返回代码为401的HTTP响应,并且我已经用以下方式重新定义了默认URL映射: class UrlMappings { static mappings = { // ... "401" (controller: 'errors',

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

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

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

         "401" (controller: 'errors', action: 'inactivityLogout')
    }
}
下面是
inactitylougout()
方法的主体:

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调用很好,但是当我试图通过单击应用程序中的直接链接导航到另一个页面时,它就不起作用了。在第二种情况下,log为空,因此不调用方法
inactivitylougout

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

有什么想法吗?我目前的解决方案有什么问题?这个问题能以完全不同的方式解决吗


谢谢

使用jQuery,我就是这么做的:

$.ajaxSetup({
   statusCode: {
     401: function () {
       $('#ajaxAuthModal').modal('show');
     }
   }
});
我把它放在一个全局JS文件中,这样我的所有ajax请求都可以处理401。然后我只显示一个模式,告诉用户他们需要再次登录。实现所需的唯一真正区别是通过ajax轮询安全资源。这将允许401函数在返回401时触发

像jQuery这样的大多数JavaScript库应该具有与
$.ajaxSetup()
类似的功能


是的,这个想法是在没有任何用户交互的情况下显示消息。只是想让用户知道他为什么注销系统

因此,本质上,一旦用户加载了页面,就没有与服务器的联系。服务器无法将消息“推送”到浏览器。因此,您需要做的是检查是否存在使用JavaScript的活动会话。你可以很容易地用定时器来完成

在main.gsp中,将javascript变量设置为
${session.maxInactiveInterval}
。这将为您提供用户会话的最大长度。只需启动一个
setTimeout(函数(){/*code在这里向用户显示*/},maxInterval)

记住在AJAX调用时重置间隔,因为页面没有被重新加载,所以不会被重置


作为补充说明,URL映射应该只在非AJAX请求上起作用,因为页面没有被重新加载,因此没有显示页面的内容。您必须使用@Gregg正在使用的类似工具来处理AJAX请求。

您是希望根据这些请求显示消息,还是希望在会话到期时自动显示消息,而不需要任何用户交互?是的,我们的想法是在不需要任何用户交互的情况下显示消息。只是想让用户知道他为什么注销系统。谢谢,这是一个很好的AJAX请求解决方案!但我还需要将用户重定向到LoginController,当他尝试导航到另一个,并在那个里显示消息时。Spring Security会在会话到期时自动将用户重定向到LoginController,但我需要了解,用户是通过直接链接到网站来访问此页面,还是因为不活动而注销。可能是我说得不够清楚,但信息不应该显示为弹出窗口,而应该显示为登录页面上的纯文本。