【问题标题】:How to differentiate between logout and session expired?如何区分注销和会话过期?
【发布时间】:2018-01-14 10:04:33
【问题描述】:

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

Case 2: Session expired : 如果用户还在登录状态时 session 已经过期,那么在访问上一页时,它必须尝试自动重定向到 sessionExpired.jsp。

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

【问题讨论】:

    标签: java jsp session session-timeout


    【解决方案1】:

    您可以通过检查 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);
        }
    }
    

    无需为额外的 cookie 烦恼。将此Filter 映射到覆盖受保护页面的url-pattern(因此不包括会话过期和登录页面!)。

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

    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.
    

    【讨论】:

    • 如果我从一个页面重定向到另一个页面,比如说登录类型页面(选择谷歌登录或默认登录)到登录页面,两者都发生在登录之前,上面的代码是否重定向到会话过期页面?
    • 理解了上面的答案,但是如果我们实现http基本身份验证机制会发生什么......在访问服务器端的任何url或servlet之前,它会向客户端抛出401......在这种情况下如何处理?
    • 如果您想要更细粒度的控制,只需替换为 FORM 身份验证即可。
    • 我不能用FORM认证代替http基本认证机制,没有这个我想实现
    【解决方案2】:

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

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

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

    【讨论】:

    • 谢谢。我要实现这个。
    • 如果我尝试使用 firefox webdeveloper 插件重新创建 cookie,代码可能会失败。
    【解决方案3】:

    如果是我,我会在注销时清除会话并在其中创建一个名为 HasLoggedOut 的布尔值,然后将其设置为 true。然后,如果此布尔值存在于会话中,您知道他们已注销,如果不存在,则会话已超时或用户根本没有登录。

    由于您仍然无法区分超时和未登录,因此我通常会决定,如果他们请求经过身份验证的页面,我只会将它们发送到会话超时页面,该页面也兼作登录页面,上面写着类似

    “糟糕,我们不知道您是谁,您的会话已超时或您尚未登录,请在下方登录”

    这就满足了这两种情况

    【讨论】:

    • 谢谢。这是个好主意,但是显示您是新用户或会话超时并不好看。
    猜你喜欢
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-18
    • 2012-05-14
    • 1970-01-01
    • 2017-06-22
    相关资源
    最近更新 更多