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

Pra*_*hat 6 java session jsp session-timeout

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

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

如何区分?我现在正在注销会话时使会话无效.

Jos*_*seK 9

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

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

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


Bal*_*usC 7

您可以通过检查是否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);
    }
}
Run Code Online (Sandbox Code Playgroud)

无需额外的饼干麻烦.此地图Filter上的url-pattern覆盖保护的页面(从而排除了sessionExpired时和登录页面!).

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

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.
Run Code Online (Sandbox Code Playgroud)