一分鐘理解Session和Cookie的關系
假設一個場景:在 Session 中保存一個變量,用戶每請求一次變量增加 1,然后把最新的值以 HTML 的方式返回給客戶端。
用戶第一次請求,Web 服務器(或者應用服務器,如 Tomcat)返回數字 1,那么此時 HTTP 傳輸已經結束,TCP 經歷四次揮手,連接關閉。
- 當頁面再次刷新時(TCP 重新連接,客戶端是新的端口)服務器端是如何知道用戶對應的 Session 的?
- 此時關閉瀏覽器 Session 是否會釋放?
眾所周知 HTTP 是無狀態的協議,它的狀態管理機制是后來增補上去的,被記錄在rfc6265(HTTP State Management Mechanism)。具體方法很簡單:
- 服務器端->客戶端增加一個新的返回頭部“Set-Cookie”,通過它設置一個 Key/Value 結構的數據;客戶端負責保存這個數據。
- 客戶端->服務器端增加一個新的請求頭部“Cookie”,把保存的 Cookie(Key/Value 結構)提交給服務器端。
這個機制就是 Cookie,Session 機制是建立在 Cookie 機制之上的。對于 JavaEE 而言:
用戶請求的業務邏輯中出現 Session 操作,并且本次請求沒有 JSESSIONID 的頭部被傳遞過來,服務器端會通過 Set-Cookie 設置上一個新的
當用戶再次請求,Cookie 中包含了 JSESSIONID,服務器端會依據此判斷出用戶所屬的 Session
所以回到開始的兩個問題:
- 服務器端通過讀取 Http 頭部 Cookie 部分 JSESSIONID 找到用戶所屬的 Session
- 關閉瀏覽器只是 JSESSIONID 這個 Cookie 被刪除;服務器端的 Session 不會被刪除。刪除時間是通過session-timeout配置的
有一種網絡攻擊方法叫 Cookie/Session 欺騙,比如某管理員用戶登錄到系統了,如果我們趁他不在電腦旁邊的時候把他的 JSESSIONID 復制走;然后打開瀏覽器訪問相同的網址,通過瀏覽器設置上 JSESSIONID,再次刷新,你會發現已經登錄成功了。也就是說服務器端其實只認 JSESSIONID,它甚至無法區分究竟有多少管理員“同時在線”。
【本文是51CTO專欄作者“邢森”的原創文章,轉載請聯系作者本人獲取授權】