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