会话验证过滤器在会话过期时注销用户

Posted

技术标签:

【中文标题】会话验证过滤器在会话过期时注销用户【英文标题】:Session validation filter which logs off the user when session is expired 【发布时间】:2011-11-14 07:32:01 【问题描述】:

我有一个会话验证过滤器,它会在会话过期时注销用户。

这是一段代码,但这不起作用。不工作意味着即使会话过期也不会重定向到登录页面。

请帮我解决这个问题。

public void doFilter(ServletRequest request, ServletResponse response, 
        FilterChain chain) throws IOException, ServletException   
    HttpServletResponse res = (HttpServletResponse) response;  
    HttpServletRequest req = (HttpServletRequest) request;  

    HttpSession s = req.getSession(false);  

    if (s==null)
    
        //redirect to login page with session expiry message   
     else   
        chain.doFilter(request, response);  
      

【问题讨论】:

您检查过重定向块中的会话 ID 吗?它在改变吗?您的软件/框架是否有可能在某处调用 getSession(true)? 【参考方案1】:

我有一个会话验证过滤器,它会在会话过期时注销用户。

老实说,这完全没有意义。如果将登录用户存储为会话的一个属性,并根据登录用户在会话中的存在来截取“登录”状态,那么您根本不需要手动注销用户会话已过期。当会话过期时,它的所有属性无论如何都会丢失,因此用户将被“自动”注销。

这是一个示例,说明如何在 servlet 的 doPost() 中登录用户,该用户由登录表单 JSP 的 POST 提交调用。

String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userService.find(username, password);

if (user != null) 
    request.getSession().setAttribute("user", user); // Login user.
    response.sendRedirect("userhome"); // Redirect to user home page.
 else 
    request.setAttribute("errormessage", "Unknown login, try again"); // Set error message.
    request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Redisplay login form.

您看,当登录有效时,用户被存储为会话属性。您的代码的剩余部分可以只检查它是否为空,以确定用户是否已登录。每当会话到期时,它会自动变为空。


即使会话过期,这也不会重定向到登录页面

我不知道您要做什么,因为最初的功能要求没有意义。但是,存在与会话到期和登录页面相关的两个常见功能需求。我猜你实际上需要其中之一:

    “当访问者请求一个仅限登录用户访问的页面时,我如何将访问者重定向到登录页面?”

    您需要创建一个filter 并将其映射到受限页面的(通用)URL 模式。在过滤器中,只需检查用户是否存在于会话中,然后继续链,否则重定向到登录页面。

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
    
        if (session == null || session.getAttribute("user") == null) 
            response.sendRedirect("login"); // No logged-in user found, so redirect to login page.
         else 
            chain.doFilter(req, res); // Logged-in user found, so just continue request.
        
    
    

    “如何在会话过期时自动将当前打开的页面重定向到登录页面?”

    <meta> 刷新与HttpSession#getMaxInactiveInterval() 结合使用。

    <meta http-equiv="refresh" content="$pageContext.session.maxInactiveInterval;url=sessionexpired.jsp">
    

    这将在会话到期时自动将当前页面重定向到给定的url$pageContext.session.maxInactiveInterval 表达式将内联会话过期时间(以秒为单位),这正是 content 属性所需要的。

【讨论】:

我有 标签,但它只是重定向到我立即指定的页面。 @Makky:显然它打印了0 好的。您能指导我如何在会话到期时自动重定向吗? @BalusC:很好的答案,但出于好奇,不使用 getSession(false) 跟踪会话的原因是什么。文档中清楚地写道,当请求没有附加现有会话时,它返回 null。 @unknown:因为您希望容器无论如何都创建一个。请注意,过滤器不会这样做,因为您不希望容器不必要地创建它,即使您不打算使用它。

以上是关于会话验证过滤器在会话过期时注销用户的主要内容,如果未能解决你的问题,请参考以下文章

Java Web 应用程序中的会话过期时如何重定向到登录页面?

会话过期的 laravel 事件监听器,因为会话过期时没有调用注销事件监听器

如何在身份验证之后和注销之前调用方法? (春季安全)

从过滤器重定向到 JSP 时传递属性:会话与请求

Laravel 身份验证会话超时

ASP.NET CORE 2.2 WEB APP中的会话过期问题