如何区分注销和会话过期?

案例1:注销:一旦我们注销,如果有人试图访问之前的版本,它必须自动重定向到login.jsp

案例2:会话已过期:如果会话在用户仍然登录时到期,则必须尝试在访问上一页时自动重定向到sessionExpired.jsp。

如何区分? 我正在注销登录时无效。

登录时,设置一个长期到期的cookie(> 24小时)。 通过将maxage设置为0,在注销时删除此cookie。

您可以检查任何未登录的用户(即无效的会话ID)。 如果cookie不存在,请将其重定向到login.jsp

如果cookie存在,则表示他的会话已过期,因此将其重定向到session-expired.jsp

您可以通过检查HttpServletRequest#getRequestedSessionId()是否未返回null (这意味着客户端已发送会话cookie并因此假定会话仍然有效)来测试过期会话,并且HttpServletRequest#isRequestedSessionIdValid()返回false (这意味着会话已在服务器端过期)。

坚果:

 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; HttpSession session = request.getSession(false); if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) { response.sendRedirect(request.getContextPath() + "/sessionexpired.jsp"); } else if (session == null || session.getAttribute("user") == null) { response.sendRedirect(request.getContextPath() + "/login.jsp"); } else { chain.doFilter(request, response); } } 

无需额外的cookies麻烦。 将此Filter映射到覆盖受保护页面的url-pattern (从而排除sessionexpired和登录页面!)。

不要忘记在受保护的页面上禁用浏览器的页面缓存,否则当您返回浏览器历史记录时,Web浏览器将从缓存中加载它们,而不是向服务器发送新请求。 您可以通过 Chain#doFilter()调用之前在同一filter中执行以下操作来实现此目的。

 response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. response.setHeader("Pragma", "no-cache"); // HTTP 1.0. response.setDateHeader("Expires", 0); // Proxies. 

如果是我,我会在注销时清除会话并在其中创建一个名为HasLoggedOut的bool,然后将其设置为true。 然后,如果会话中存在此bool,则表示他们已注销,如果不存在,则会话已超时或用户从未登录。

由于您仍然无法区分超时和未登录,我通常会做出决定,如果他们请求经过身份validation的页面,我会将它们发送到会话超时页面,该页面也可以作为登录页面使用

“哎呀,我们不知道你是谁,要么你的会话超时还是你还没有登录,请在下面登录”

这适用于两种情况