如何正确使JSP会话失效?

9
所以这里的问题是,当用户退出我的网站时,他们仍然可以点击返回按钮并继续使用该网站。为了跟踪用户是否已登录,我创建了一个会话属性“isActive”。当用户登录时,该属性设置为true,并在注销时在会话无效之前(冗余地)删除。此外,在每个页面上,我都检查属性是否存在。
我还在头标签中指定了页面不应被缓存。
尽管如此,用户仍然能够在浏览器上点击返回,并继续使用网站,就好像他们从未注销过一样。
有没有想法如何解决这个问题?
以下是代码:
登录Servlet:
...
session.setAttribute("isActive", true);
//Redirect to home page.

检查已登录的JSP页面:

<c:if test='${empty sessionScope.isActive || sessionScope.isActive != true}'>
     <c:redirect url="/index.jsp?message=Session Timed Out."/>
</c:if>

注销Servlet:

request.getSession().removeAttribute("isActive");
request.getSession().invalidate();
response.sendRedirect("index.jsp");

在 Head 标签内:

<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="Sat, 01 Dec 2001 00:00:00 GMT">

谢谢

3个回答

11
meta标签是不够的,你需要将它们添加为完整的响应头。Web浏览器依赖于它们。使用Filter会很有帮助。此外,Cache-Control头不完整(在Firefox等浏览器中无法正常工作)。
doFilter()方法中实现这个功能,使用一个Filter,将其映射到一个url-pattern,例如*.jsp(如果你想覆盖所有JSP页面)。
HttpServletResponse res = (HttpServletResponse) response;
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
res.setHeader("Pragma", "no-cache"); // HTTP 1.0.
res.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(request, response);

这样可以强制浏览器向服务器发出真正的请求,而不是从浏览器缓存中显示页面。此外,您应该使用Filter来检查已登录用户的存在,而不是使用JSP / JSTL。

相关问题:


不用谢。别忘了标记最有帮助的答案为已接受。另请参阅http://stackoverflow.com/faq。 - BalusC

2

在目标页面上检查会话是否仍处于活动状态是不好的做法,最好使用Filter进行检查。

如果在过滤器中,request.getSession().getAttribute("isActive")返回了某些内容,则用户仍然登录,您只需链接即可;否则,您将重定向到登录页面。

例如:

public class ActiveFilter implements Filter {
   public void init(FilterConfig filterConfig) 
   }
   public void destroy() {
   }
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      HttpServletRequest req = (HttpServletRequest) request;
      HttpServletResponse res = (HttpServletResponse) response;
      if (req.getSession().getAttribute("isActive") == null){
          res.sendRedirect("/index.jsp");
      }else{
          chain.doFilter(request, response);
      }
   }
}

资源:


谢谢,你知道如何让它在除了index.jsp之外的每个页面上都起作用吗?看起来web.xml中的url-pattern标签不支持正则表达式。 - Morglor

0

我所有的JSP都有no-cache头(通过@include指令)。我在应用程序的根目录下有一个logout.jsp,其中包含以下行:

HttpSession sessIfAny = request.getSession(false);
if (sessIfAny != null) sessIfAny.invalidate();

这样可以避免创建不必要的会话。

web.xml 需要使 logout.jsp 免于认证:

<!-- Resources excepted from authentication -->
<security-constraint>
    <web-resource-collection>
        <web-resource-name>excepted</web-resource-name>
        <url-pattern>/logout.jsp</url-pattern>
        <url-pattern>/favicon.ico</url-pattern>
        <!-- ... other resources -->
    </web-resource-collection>
    <!-- no auth-constraint -->
</security-constraint>

这样做可以防止在会话过期时显示登录页面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接