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

Java Cookie 與 Session 深度解析:原理、差異與最佳實踐

     編輯:Java 相關知識

前言:為什麼需要會話追蹤?

HTTP 是無狀態協議,每次請求都是獨立的。為了識別用戶身份、維持登入狀態、購物車功能等,我們需要會話追蹤技術。Cookie 和 Session 是兩種最主流的解決方案。

Cookie:客戶端狀態管理

運作機制

伺服器在響應頭中設置 Set-Cookie,瀏覽器儲存後,後續請求會自動攜帶該 Cookie。適用於輕量級數據儲存,如「記住我」、用戶偏好設定。

關鍵屬性

屬性說明
Domain/Path控制 Cookie 的作用範圍
Max-Age/Expires控制生命週期,Session Cookie 隨瀏覽器關閉銷毀
Secure僅 HTTPS 傳輸
HttpOnly防止 XSS 攻擊,JavaScript 無法讀取
SameSite防禦 CSRF 攻擊

Java 代碼示例

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws IOException {
    response.setContentType("text/html;charset=utf-8");
    PrintWriter out = response.getWriter();
    
    Cookie[] cookies = request.getCookies();
    String name = getCookieValue(cookies, "username");
    
    if (name == null) {
        Cookie cookie = new Cookie("username", "user123");
        cookie.setMaxAge(60 * 60 * 24 * 7); // 7天
        cookie.setHttpOnly(true);
        response.addCookie(cookie);
        out.println("首次訪問,已設置 Cookie");
    } else {
        out.println("歡迎回來," + name);
    }
}

private String getCookieValue(Cookie[] cookies, String key) {
    if (cookies != null) {
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(key)) {
                return cookie.getValue();
            }
        }
    }
    return null;
}

Session:伺服端狀態管理

核心原理

Session 數據存儲在伺服器內存(或 Redis/Memcached),客戶端僅保存 Session ID(通常為 JSESSIONID Cookie)。解決了 Cookie 帶寬開銷大、安全性差的問題。

Session 生命週期管理

  • 創建:首次調用 request.getSession()
  • 存取:setAttribute/getAttribute
  • 銷毀:超時、手動 invalidate()、伺服器關閉

分散式 Session 解決方案

單機 Session 無法支撐集群環境,主流方案:

  • Session 複製:Tomcat DeltaManager,僅適合小集群
  • Redis/Memcached 共享:推薦方案,高性能、可擴展
  • Spring Session:提供透明化整合,支援多種存儲後端

安全性對比與最佳實踐

維度CookieSession
存儲位置客戶端伺服端
數據安全性低(可被竄改/竊取)高
存儲容量4KB/域受限於伺服器內存
適用場景非敏感、輕量數據用戶身份、權限、購物車

防重複提交:Token 模式

// 表單生成時
String token = UUID.randomUUID().toString();
session.setAttribute("form_token", token);
// 頁面隱藏域: <input type="hidden" name="token" value="${token}">

// 提交驗證
String submittedToken = request.getParameter("token");
String sessionToken = (String) session.getAttribute("form_token");
if (sessionToken != null && sessionToken.equals(submittedToken)) {
    session.setAttribute("form_token", UUID.randomUUID().toString()); // 更新 token
    // 業務處理
} else {
    // 重複提交或非法請求
}

總結

理解 Cookie 與 Session 的本質差異,根據業務場景選擇合適方案。現代 Web 開發中,建議採用「Session 存核心狀態 + Cookie 存非敏感偏好」的混合策略,並配合 Redis 實現分散式 Session 共享。

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