HTTP會話保持技術Cookie與Session
摘要:本文介紹Cookie與Session原理,對於Cookie與Session的屬性詳情和其他擴充套件不做探討。必須的前導知識:HTTP協議原理。
一、HTTP協議的缺陷——無狀態
因為HTTP1.0被設計成是基於TCP協議的短連線,即完成一次“請求-應答”之後會斷開連線。所以,伺服器接到一次HTTP請求時不知道之前是否曾經收到過同一個客戶端傳送來的請求,即“無狀態”。這意味著如果伺服器處理請求時需要上次請求的資訊,客戶端必須重傳全部資訊,這樣可能導致每次連線傳送的資料量巨增。
思考1:為什麼HTTP被設計成短連線?能不能是長連線,這樣就儲存了會話狀態?
二、Cookie技術——客戶端會話保持
(一).Cookie的原理
Cookie是通過HTTP協議擴充套件實現的,即在HTTP請求頭裡面增加Cookie欄位,用於儲存客戶端資訊。
Cookie的原理和實現步驟參考圖1:
圖1:Cookie實現會話保持步驟截圖
1.客戶端向Web伺服器發起HTTP請求;
2.伺服器在返回響應時,在HTTP響應頭中設定Set-Cookie欄位,該欄位儲存客戶端資訊和狀態;
Java實現:
Cookie cookie = new Cookie("username","zhang3"); response.addCookie(cookie);
3.客戶端解析伺服器HTTP響應報頭中的Set-Cookie欄位,並根據其生命週期建立不同型別的Cookie(例如持久化Cookie就會在客戶端硬碟上建立Cookie檔案)。之後客戶端每次傳送HTTP請求報文時,都會在請求報頭中增加Cookie欄位。
4.伺服器接收客戶端的HTTP請求之後,從報文頭中取出Cookie資料,來校驗客戶端狀態或身份資訊。
(二)Cookie的屬性
Cookie有一些基礎屬性(參考:rfc2965),其中最重要的是有效期和域名。
1.Cookie的有效期
Cookie的有效期有兩個屬性可以設定,Expires或Max-Age。Expires規定Cookie在一個具體的時刻失效;Max-Age指定從建立Cookie開始,到Max-Age秒之後失效。這些Cookie會在客戶端由瀏覽器持久化到磁碟上(win7位置:C:\Users\使用者名稱\AppData\Roaming\Microsoft\Windows\Cookies。參考圖2)。如果不顯示設定有效期,Cookie會在連線斷開後失效。
圖2:windows7中儲存的Cookie檔案截圖
Java實現:
Cookie cookie = new Cookie("username","zhang3"); cookie.setMaxAge(30*24*60*60);//單位秒;-1為臨時;0刪除cookie response.addCookie(cookie);
2.Cookie的域名
出於對隱私安全的考慮,Cookie設計為不可跨域名。即www.google.com頒發的Cookie不會被提交到域名www.baidu.com,即使提交過去也不可用。
Java實現:
Cookie cookie = new Cookie("username","zhang3"); cookie.setMaxAge(30*24*60*60);//單位秒;-1為臨時;0刪除cookie cookie.setDomain("mydomain.com"); response.addCookie(cookie);View Code
思考2:能不能利用Cookie檔案獲得他人許可權?
(三)Cookie的應用
1.購物車
1) 伺服器遍歷使用者選擇的商品
2) 將商品放入集合類
3) 將集合存入Cookie
Java虛擬碼:
for(Good good:goodSelected){ goodList.put(good.name+"-"+good.price+"-"+good.num) } cartCookie = new Cookie("cart",goodList); response.addCookie(cartCookie);
2.上次登入時間
Java虛擬碼:
if(cookie == null){//如果是第一次登入 loginCookie = new Cookie("lastTime",now()); loginCookie.setMaxAge(7*24*60*60); response.addCookie(loginCookie); }else{ lastTime = loginCookie.getValue(); out.write("歡迎回來,您上次訪問時間是:"+lastTime); loginCookie.setValue(now());//更新登入時間 response.addCookie(loginCookie); }View Code
3.自動登入
最簡單的設計是把使用者名稱密碼寫入Cookie中,但是有安全隱患,一般存一個hash值。
一個簡易的Java實現:
private static final String KEY="真相永遠只有一個"; ssid = MD5(KEY+"zhang3"); Cookie u_cookie = new Cookie("username","zhang3"); Cookie ssid_cookie = new Cookie("ssid",); response.addCookie(u_cookie); response.addCookie(ssid_cookie);View Code