Java Web登录验证与自动登录实现指南

周予安
周予安
发布时间:2026-10-13 | 2人浏览过
原创

在Java Web开发中,保障用户数据安全需要校验登录状态,提升用户体验则需要支持自动登录。本文将详细演示如何利用Servlet过滤器(Filter)进行会话拦截,以及结合HTTP Cookie实现“记住我”功能的完整代码路径与配置流程。

验证用户登录状态

在Web应用中,我们需要保护某些页面或操作不被未授权用户访问。最简单有效的方式是在请求到达目标资源之前,检查当前会话(Session)中是否存在特定的用户标识属性。如果不存在,则视为未登录,并重定向至首页或登录页。

第1步:创建过滤类

目的:实现一个统一的入口拦截器,专门用于检查登录权限。

操作:新建一个类实现 javax.servlet.Filter 接口。核心逻辑在 doFilter 方法中执行。

  1. 将传入的请求对象强转为 HttpServletRequest,以便调用 getSession() 获取当前会话。
  2. 通过 getSession().getAttribute("user") 检查是否存在已记录的用户名。这里假设登录成功后会在Session中存储名为 "user" 的属性。
  3. 若属性为空(null),说明未登录:
    • 向Request作用域设置提示信息。
    • 使用Response对象的 sendRedirect 重定向到登录入口(如 /index.jsp)。
  4. 若属性存在,说明已登录,调用 chain.doFilter(request, response) 放行请求继续处理。
package cn.hongxin.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LoginFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化逻辑
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpSession ss = req.getSession();

        // 从 session 中获取 user
        if (ss.getAttribute("user") == null) {
            System.err.println("你还没有登录");
            req.getSession().setAttribute("msg", "请你先登录");
            // 重定向到登录页面
            String contextPath = req.getContextPath();
            resp.sendRedirect(contextPath + "/index.jsp");
        } else {
            // 放行
            chain.doFilter(request, response);
        }
    }

    public void destroy() {
        // 销毁逻辑
    }
}

第2步:配置 web.xml

目的:告诉服务器哪些页面受该过滤器管辖。

操作:在 WEB-INF/web.xml 中注册Filter并设置匹配模式。

<filter>
  <filter-name>login</filter-name>
  <filter-class>cn.itcast.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>login</filter-name>
  <!-- 仅拦截jsp目录下的资源 -->
  <url-pattern>/jsps/*</url-pattern>
  <url-pattern>/views/*</url-pattern>
</filter-mapping>

实现自动登录功能

自动登录机制通常被称为“记住我”(Remember Me)。其原理是:用户首次登录时,服务端将包含用户标识的Cookie发送并保存到客户端浏览器;下次用户访问时,过滤器读取该Cookie,自动补全Session信息,从而实现无感登录。

第1步:开发登录前端界面

目的:提供用户输入账号及选择是否自动登录的交互入口。

操作:在JSP中使用EL表达式判断当前是否已登录。未登录时展示表单,提供单选框选项(不自动、1天、1周)。

<c:choose>
  <c:when test="${empty sessionScope.name}">
    <form name="x" method="post" action="<c:url value='/LoginServlet'/>">
      Name: <input type="text" name="name"/><br/>
      auto:
      <input type="radio" name="auto" value="-1">不自动登录<br/>
      <input type="radio" name="auto" value="1">1天<br/>
      <input type="radio" name="auto" value="7">1周<br/>
      <input type="submit" value="提交"/>
    </form>
  </c:when>
  <c:otherwise>
    你已经登录了: ${name}<br/>
    <a href="<c:url value='/LoginServlet'/>">退出</a>
  </c:otherwise>
</c:choose>

第2步:服务端处理登录并保存Cookie

目的:接收用户的登录请求,并在Session建立后,根据用户的选择决定是否下发Cookie。

操作:在 LoginServlet 的 doPost 方法中:

  1. 获取用户名和自动登录时长参数。
  2. 将用户名存入 session.setAttribute("name", name)。
  3. 解析自动登录参数:若非 "-1"(即选择了自动登录),则将天数转换为秒数(1天=86400秒)。
  4. 实例化 Cookie,设置MaxAge(存活时间)和Path(有效路径)。
  5. 务必注意:Cookie的Path必须设置为 request.getContextPath(),确保同项目下任何Servlet都能读取该Cookie。
public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    // 接收用户姓名
    String name = request.getParameter("name");
    String auto = request.getParameter("auto");

    // 将用户信息放到 session
    request.getSession().setAttribute("name", name);

    // 判断是否需要设置自动登录
    if (!auto.equals("-1")) {
        int day = Integer.parseInt(auto); // 1 | 7
        int seconds = 60 * 60 * 24 * day;

        // 声明 cookie
        Cookie c = new Cookie("autoLogin", name);
        c.setMaxAge(seconds); // 设置存活时间
        c.setPath(request.getContextPath()); // 设置路径为项目根目录

        // 保存cookie到客户端
        response.addCookie(c);
    }
}

第3步:开发自动登录过滤器

目的:在所有页面加载前检查本地是否有有效的“记住我”凭证。

操作:创建一个 AutoFilter,同样实现Filter接口。由于要让所有页面都经历此检查,它需要挂载到 /* 上,但需要注意避免死循环和性能浪费(下文有优化建议)。

  1. 在 doFilter 中读取所有Cookie数组 req.getCookies()。
  2. 遍历数组,寻找名称为 autoLogin 的Cookie。
  3. 若找到且值不为空,将值写入Session req.getSession().setAttribute("name", value)。
  4. 最后无论是否完成自动登录,都必须调用 chain.doFilter 放行请求。
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {

    HttpServletRequest req = (HttpServletRequest) request;

    // 获取所有的 cookies
    Cookie[] cs = req.getCookies();
    if (cs != null) {
        for (Cookie c : cs) {
            // 如果存在自动登录的 cookie
            if (c.getName().equals("autoLogin")) {
                String value = c.getValue();
                // 登录成功是指:手动将身份信息注入 Session
                req.getSession().setAttribute("name", value);
                break;
            }
        }
    }
    // 不管是否自动登录成功,都要放行
    chain.doFilter(request, response);
}

第4步:配置自动登录过滤器

目的:确保所有URL请求都会经过自动登录的逻辑判断。

操作:在 web.xml 中追加以下配置:

<filter>
  <filter-name>auto</filter-name>
  <filter-class>cn.itcast.filter.AutoFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>auto</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

安全退出与代码优化

简单的实现往往忽略细节,导致退出失效或性能冗余。我们需要优化退出逻辑以及过滤器的执行顺序。

第1步:开发退出逻辑

目的:清除服务端Session并作废客户端Cookie。

操作:在退出处理的Servlet中:

  1. 调用 request.getSession().invalidate() 使当前Session失效。
  2. 构造一个同名的 Cookie(key为 autoLogin),但将其 setMaxAge(0),这会指示浏览器立即删除该Cookie。
  3. 设置路径时必须与原保存Cookie的路径一致,否则无法正确覆盖或删除。
// 模拟退出处理
System.out.println("用户退出");
// 删除整个session
request.getSession().invalidate();

// 清空Cookie
Cookie c = new Cookie("autoLogin", "ddd"); // 值随意
c.setMaxAge(0);                             // 立即过期
c.setPath(request.getContextPath());        // 保持原路径一致
response.addCookie(c);

// 跳转回首页
response.sendRedirect(request.getContextPath() + "/index.jsp");

第2步:代码性能优化

在上述逻辑中,当用户进行正常的账号密码登录时(调用LoginServlet),也会触发 AutoFilter 的执行。虽然这不会报错,但增加了不必要的Cookie遍历开销。此外,直接拦截Logout也会导致异常。因此,建议在 AutoFilter 中进行如下改进:

  • 排除登录接口:在 doFilter 头部检查请求URI,如果是指向 LoginServlet 的请求,直接 break 或 continue,不进行Cookie读取。
  • 排除退出接口:同理,如果是Logout请求,也跳过自动登录逻辑。

以上就是Java实现验证用户登录状态与Cookie自动登录的详细内容,更多关于Java Filter与Cookie应用的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表