我有一个30分钟会话超时的网络应用程序。 设计是当会话被删除时,用户将自动注销并需要再次登录。
问题是我的网页上有一个新闻自动收录器,它通过AJAX呼叫每5分钟更新一次。 newsticker AJAX调用自然会重置会话超时,因此用户不会被注销。
我想通过编写一个过滤器来实现我自己的不活动检测器,当用户获取/发布页面时,除了新闻报道器之外,该过滤器更新lastActive变量(存储在会话中)。
然后我想,也许有办法排除某些调用重置会话超时。 所以我搜索并找到了一些与asp相关的答案,但对于jsp和Weblogic却没有。
有没有办法排除某些URL:s重置会话超时?
I have a web app with a 30 min session timeout. The design is that when the session is dropped the user is automatically logged out and needs to sign in again.
Problem is that I have a news ticker on my web page that updates every 5 minutes via an AJAX call. The newsticker AJAX call naturally resets the session timeout, so the users don't get logged out.
I was thinking of implementing my own inactivity detector by writing a filter that updates a lastActive variable (stored in the session) whenever the user gets/posts a page, except for the news ticker.
Then I was thinking, maybe there is a way to exclude certain calls from resetting the session timeout. So I searched and found some answers relating to asp, but nothing for jsp and Weblogic.
Is there a way to exclude certain URL:s from resetting the session timeout?
最满意答案
由于我无法通过配置找到任何方法,所以我最终编写了一个过滤器,当有足够的时间没有用户活动时,该过滤器使会话无效。 我已经有了另一个过滤器,可以将没有会话的用户重定向到登录页面。 我在过滤器链中的授权过滤器之前添加了SessionTimeoutFilter 。
下面的代码略有剥离。 我删除了所有内部依赖项,这就是为什么所有值都是硬编码的。
public class SessionTimeoutFilter implements Filter { private final long TIMEOUT = 1800L; // 30 minutes in seconds private final String LAST_ACTIVITY = "LAST_ACTIVITY"; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest) { HttpServletRequest theRequest = (HttpServletRequest) request; Long now = (new Date()).getTime(); HttpSession session = theRequest.getSession(false); if (session != null) { Long lastActivity = (Long) session.getAttribute(LAST_ACTIVITY); if (lastActivity == null) { // The first call for this session. lastActivity = now; } if (now - lastActivity > TIMEOUT*1000L) { // User timed out. session.invalidate(); } else if (isUserCall(theRequest)) { // Reset inactivity timer session.setAttribute(LAST_ACTIVITY, now); } } } chain.doFilter(request, response); } /** * @return true if the URI indicates user activity, * false if it is an automatic call */ private boolean isUserCall(HttpServletRequest request) { String uri = request.getRequestURI(); if (uri.contains("NewsTicker")) { return false; } return true; }Since I couldn't find any way to do this by configuration I ended up writing a filter that invalidates the session when enough time has passed without user activity. I already had another filter in place that redirects users without a session to the login page. I added the SessionTimeoutFilter just before the authorisation filter in the filter chain.
The code below is slightly stripped. I have removed all internal dependencies, that is why all values are hardcoded.
public class SessionTimeoutFilter implements Filter { private final long TIMEOUT = 1800L; // 30 minutes in seconds private final String LAST_ACTIVITY = "LAST_ACTIVITY"; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest) { HttpServletRequest theRequest = (HttpServletRequest) request; Long now = (new Date()).getTime(); HttpSession session = theRequest.getSession(false); if (session != null) { Long lastActivity = (Long) session.getAttribute(LAST_ACTIVITY); if (lastActivity == null) { // The first call for this session. lastActivity = now; } if (now - lastActivity > TIMEOUT*1000L) { // User timed out. session.invalidate(); } else if (isUserCall(theRequest)) { // Reset inactivity timer session.setAttribute(LAST_ACTIVITY, now); } } } chain.doFilter(request, response); } /** * @return true if the URI indicates user activity, * false if it is an automatic call */ private boolean isUserCall(HttpServletRequest request) { String uri = request.getRequestURI(); if (uri.contains("NewsTicker")) { return false; } return true; }更多推荐
发布评论