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

6

案例1:退出登录:一旦我们退出登录,如果有人试图访问以前的页面,它必须自动重定向到login.jsp。

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

如何区分?我目前在注销时使会话无效。

3个回答

9

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

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

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


谢谢。我将要实现这个。 - Prabhat
如果我尝试使用Firefox Web开发者插件重新创建Cookie,则代码可能会失败。 - Dead Programmer

8
您可以通过检查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上。

不要忘记在受保护的页面上禁用浏览器页面缓存,否则当您在浏览器历史记录中返回时,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.

如果我从一个页面重定向到另一个页面,比如选择 Google 登录或默认登录的登录类型页面到登录页面,在登录之前都会发生,那么上述代码是否会重定向到会话过期页面? - Dileep
明白了上面的回答,但如果我们实现HTTP基本身份验证机制会发生什么呢?在访问服务器端的任何URL或Servlet之前,它将向客户端抛出401错误。在这种情况下该如何处理? - moh
如果您想要更细粒度的控制,只需使用FORM身份验证即可。 - BalusC
我无法将HTTP基本身份验证机制替换为表单身份验证,没有这个我想要实现。 - moh

1

如果是我,我会在注销时清除会话并在其中创建一个名为HasLoggedOut的布尔变量,然后将其设置为true。然后如果会话中存在这个布尔变量,你就知道他们已经注销了;如果不存在,那么会话可能已经超时或者用户根本没有登录。

由于你仍然无法区分超时和未登录的情况,我通常会做出这样的决定:如果他们请求一个需要身份验证的页面,我会直接将他们发送到会话超时页面,这也可以作为一个登录页面,上面显示类似于以下内容的提示:

"哎呀,我们不知道你是谁,你的会话可能已经超时或者你还没有登录,请在下面登录"

这样可以同时适应这两种情况。


谢谢。这是个好主意,然而显示你是新用户或者你的会话已超时并不好看。 - Prabhat

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