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

Servlet + JDBC 實現用戶登錄驗證與 Session 管理完整範例

     編輯:Java 相關知識

功能流程

  1. LoginServlet — 顯示登錄表單(GET)。
  2. LoginClServlet — 接收提交,PreparedStatement 防注入查詢,驗證成功創建 HttpSession,重定向歡迎頁。
  3. WelcomeServlet — 攔截未登錄請求,校驗 Session,顯示歡迎信息。

代碼實現

1. 登錄頁面 Servlet (LoginServlet)

package com.bai;

import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.*;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("");
        out.println("

用戶登錄

"); out.println("
"); out.println("用戶名:
"); out.println("密碼:
"); out.println(""); out.println("
"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); // 表單提交也走 doGet 邏輯(實際專案分離) } }

2. 登錄處理 Servlet (LoginClServlet)

package com.bai;

import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.*;
import java.sql.*;

public class LoginClServlet extends HttpServlet {
    private static final String SQL = "SELECT passwd FROM users WHERE username = ? LIMIT 1";
    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/sqdb";
    private static final String DB_USER = "root";
    private static final String DB_PASS = "root";

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("passwd");

        try (Connection conn = DriverManager.getConnection(JDBC_URL, DB_USER, DB_PASS);
             PreparedStatement ps = conn.prepareStatement(SQL)) {

            ps.setString(1, username);
            try (ResultSet rs = ps.executeQuery()) {
                if (rs.next()) {
                    String dbPass = rs.getString("passwd");
                    if (password.equals(dbPass)) { // 實際應用應用 BCrypt 比對哈希
                        HttpSession session = req.getSession(true);
                        session.setMaxInactiveInterval(30 * 60); // 30 分鐘
                        session.setAttribute("username", username);
                        resp.sendRedirect("welcome");
                        return;
                    }
                }
                // 驗證失敗
                resp.sendRedirect("login");
            }
        } catch (SQLException e) {
            throw new ServletException("數據庫錯誤", e);
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

3. 歡迎頁 Servlet (WelcomeServlet)

package com.bai;

import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.*;

public class WelcomeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession(false); // 不自動創建
        String username = (session != null) ? (String) session.getAttribute("username") : null;

        if (username == null) {
            resp.sendRedirect("login");
            return;
        }

        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("");
        out.println("

歡迎, " + username + "!

"); out.println("退出登錄"); out.println(""); } }

4. 登出 Servlet (可選)

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        HttpSession session = req.getSession(false);
        if (session != null) session.invalidate();
        resp.sendRedirect("login");
    }
}

web.xml 註冊 (或用 @WebServlet 註解)

<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.bai.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>LoginClServlet</servlet-name>
    <servlet-class>com.bai.LoginClServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LoginClServlet</servlet-name>
    <url-pattern>/logincl</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>WelcomeServlet</servlet-name>
    <servlet-class>com.bai.WelcomeServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>WelcomeServlet</servlet-name>
    <url-pattern>/welcome</url-pattern>
</servlet-mapping>

安全加固清單

  • ✅ PreparedStatement 防 SQL 注入。
  • ✅ 密碼不應明文存儲,使用 BCrypt/Argon2 哈希(BCrypt.checkpw(input, hash))。
  • ✅ Session 設置 HttpOnly、Secure(HTTPS 環境)、SameSite=Strict。
  • ✅ 登錄失敗通用提示(「用戶名或密碼錯誤」),不洩露用戶是否存在。
  • ✅ 添加驗證碼/限流防暴力破解。
  • ✅ 關鍵操作記錄審計日誌(IP、時間、結果)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved