首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Web 自動登入實作:Cookie 持久化與 Filter 驗證機制

     編輯:Java 相關知識

自動登入核心原理

自動登入讓用戶在瀏覽器關閉後再次訪問時,無需重複輸入帳密即可恢復登入狀態。核心機制:登入成功時將用戶識別資訊加密存儲於客戶端 Cookie,後續請求攜帶該 Cookie 時,伺服端驗證並自動重建 Session。

Cookie 關鍵屬性配置

屬性說明自動登入設定建議
name/value鍵值對,如 autoLogin / username值建議加密或使用 Token,避免明文存儲敏感資訊
maxAge生存秒數,-1 為會話級,0 刪除依「記住我」選項設定:1天=86400、7天=604800
pathCookie 生效路徑前綴設為 request.getContextPath(),全站生效
domain跨子域共享需跨子域時設定(如 .example.com)
secure僅 HTTPS 傳輸生產環境必須啟用
httpOnly禁止 JavaScript 讀取防 XSS,必須啟用

完整實作流程

步驟 1:登入頁面(JSP + JSTL)

<c:choose>
  <c:when test="${empty sessionScope.name}">
    <form method="post" action="<c:url value='/LoginServlet'/>">
      帳號: <input type="text" name="name"/><br/>
      自動登入:
      <input type="radio" name="auto" value="-1" checked> 不自動登入 <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:登入 Servlet 處理與 Cookie 寫入

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String name = request.getParameter("name");
    String auto = request.getParameter("auto");
    
    // 驗證用戶合法性(略,實際應查詢資料庫)
    request.getSession().setAttribute("name", name);
    
    if (!"-1".equals(auto)) {
      int days = Integer.parseInt(auto); // 1 或 7
      int seconds = 60 * 60 * 24 * days;
      
      Cookie cookie = new Cookie("autoLogin", name); // 實際應存加密 Token
      cookie.setMaxAge(seconds);
      cookie.setPath(request.getContextPath());
      cookie.setHttpOnly(true);
      cookie.setSecure(request.isSecure()); // 僅 HTTPS 時 true
      response.addCookie(cookie);
    }
    response.sendRedirect(request.getContextPath() + "/index.jsp");
  }
}

步驟 3:自動登入 Filter(攔截所有請求)

@WebFilter(urlPatterns = "/*")
public class AutoLoginFilter implements Filter {
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    
    // 排除登入頁與靜態資源,避免重複處理
    String uri = req.getRequestURI();
    if (uri.endsWith("/LoginServlet") || uri.contains("/static/")) {
      chain.doFilter(request, response);
      return;
    }
    
    // 檢查 Session 是否已有用戶
    if (req.getSession().getAttribute("name") == null) {
      Cookie[] cookies = req.getCookies();
      if (cookies != null) {
        for (Cookie c : cookies) {
          if ("autoLogin".equals(c.getName())) {
            String username = c.getValue(); // 實際應驗證 Token 有效性
            // 這裡可進一步查詢資料庫驗證 Token 對應用戶是否存在
            req.getSession().setAttribute("name", username);
            break;
          }
        }
      }
    }
    chain.doFilter(request, response);
  }
}

步驟 4:登出處理(清除 Session 與 Cookie)

@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // 1. 使 Session 失效
    request.getSession().invalidate();
    
    // 2. 刪除自動登入 Cookie
    Cookie cookie = new Cookie("autoLogin", "");
    cookie.setMaxAge(0);
    cookie.setPath(request.getContextPath());
    response.addCookie(cookie);
    
    response.sendRedirect(request.getContextPath() + "/index.jsp");
  }
}

進階優化與安全強化

Token 化設計(替代明文用戶名)

  • 登入成功生成隨機 UUID Token,資料庫存 token -> user_id, expiry 映射
  • Cookie 存 Token,自動登入時查詢資料庫驗證 Token 有效性並刷新過期時間
  • 登出/修改密碼/異地登入時撤銷對應 Token

登入驗證 Filter(保護受限資源)

@WebFilter(urlPatterns = {"/jsps/*", "/views/*"})
public class LoginRequiredFilter implements Filter {
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse resp = (HttpServletResponse) response;
    
    if (req.getSession().getAttribute("user") == null) {
      req.getSession().setAttribute("msg", "請先登入");
      resp.sendRedirect(req.getContextPath() + "/index.jsp");
    } else {
      chain.doFilter(request, response);
    }
  }
}

效能優化:排除不需自動登入的路徑

在 AutoLoginFilter 中針對登入 Servlet、靜態資源、API 端點等跳過 Cookie 解析,減少無謂運算。

總結

自動登入 = 持久化 Cookie + Filter 攔截驗證 + Session 重建。生產環境務必採用 Token 機制、啟用 HttpOnly/Secure、實作 Token 撤銷與異地登入檢測,平衡使用者體驗與帳戶安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved