1. 程式人生 > >詳解session、cookie、記住我的登入狀態

詳解session、cookie、記住我的登入狀態

Cookie的機制

Cookie是瀏覽器(User Agent)訪問一些網站後,這些網站存放在客戶端的一組資料,用於使網站等跟蹤使用者,實現使用者自定義功能。

Cookie的Domain和Path屬性標識了這個Cookie是哪一個網站傳送給瀏覽器的;Cookie的Expires屬性標識了Cookie的有 效時間,當Cookie的有效時間過了之後,這些資料就被自動刪除了。

如果不設定過期時間,則表示這個Cookie生命週期為瀏覽器會話期間,只要關閉瀏覽器視窗,Cookie就消失了。這種生命期為瀏覽會話期的 Cookie被稱為會話Cookie會話Cookie一般不儲存在硬碟上而是儲存在記憶體裡。如果設定了過期時間,瀏覽器就會把Cookie儲存到硬碟 上,關閉後再次開啟瀏覽器,這些Cookie依然有效直到超過設定的過期時間。儲存在硬碟上的Cookie可以在不同的瀏覽器程序間共享,比如兩個IE窗 口。而對於儲存在記憶體的Cookie,不同的瀏覽器有不同的處理方式。

Session的機制

Session是存放在伺服器端的類似於HashTable結構(每一種Web開發技術的實現可能不一樣,下文直接稱之為HashTable)來存放使用者 資料,當瀏覽器第一次傳送請求時,伺服器自動生成了一個HashTable和一個Session ID用來唯一標識這個HashTable,並將其通過響應傳送到瀏覽器。當瀏覽器第二次傳送請求,會將前一次伺服器響應中的Session ID放在請求中一併傳送到伺服器上,伺服器從請求中提取出Session ID,並和儲存的所有Session ID進行對比,找到這個使用者對應的HashTable。

一般情況下,伺服器會在一定時間內(預設20分鐘)儲存這個HashTable,過了時間限制,就會銷燬這個HashTable。在銷燬之前,程式設計師可以 將使用者的一些資料以Key和Value的形式暫時存放在這個HashTable中。當然,也有使用資料庫將這個HashTable序列化後儲存起來的,這 樣的好處是沒了時間的限制,壞處是隨著時間的增加,這個資料庫會急速膨脹,特別是訪問量增加的時候。一般還是採取前一種方式,以減輕伺服器壓力。

Session的客戶端實現形式(即Session ID的儲存方法)

一般瀏覽器提供了兩種方式來儲存,還有一種是程式設計師使用HTML隱藏域的方式自定義實現:

[1] 使用Cookie來儲存,這是最常見的方法,本文“記住我的登入狀態”功能的實現正式基於這種方式的。伺服器通過設定Cookie的方式將Session ID傳送到瀏覽器。如果我們不設定這個過期時間,那麼這個Cookie將不存放在硬碟上,當瀏覽器關閉的時候,Cookie就消失了,這個Session ID就丟失了。如果我們設定這個時間為若干天之後,那麼這個Cookie會儲存在客戶端硬碟中,即使瀏覽器關閉,這個值仍然存在,下次訪問相應網站時,同 樣會發送到伺服器上。

[2] 使用URL附加資訊的方式,也就是像我們經常看到JSP網站會有aaa.jsp?JSESSIONID=*一樣的。這種方式和第一種方式裡面不設定 Cookie過期時間是一樣的。

[3] 第三種方式是在頁面表單裡面增加隱藏域,這種方式實際上和第二種方式一樣,只不過前者通過GET方式傳送資料,後者使用POST方式傳送資料。但是明顯後 者比較麻煩。

實現“記住我的登入狀態”的功能

前面我們瞭解到,如果我們將Session ID通過Cookie傳送到客戶端的時候設定其過期時間為1年,那麼在今後的一年時間內,客戶端訪問我的網站的時候都回將這個Session ID值傳送到伺服器上,伺服器根據這個Session ID從記憶體或者資料庫裡面恢復存放Key-Value對的Hashtable。

其實這已經很好的實現了我們的功能了。但是,前面也提到了,實際上Session並不會一直都存在的,過了一定的時間之後,伺服器上的Session就被 銷燬了,以減輕伺服器的訪問壓力。當伺服器上的資料被銷燬後,即使客戶端上存放了Cookie也沒有辦法“記住我的登入狀態”了。

通用的實現辦法是,將使用者的使用者名稱和加密之後的密碼也通過Cookie的方式存放在客戶端,當伺服器上的Session銷燬以後,使用Cookie裡面存 放的使用者名稱和加密之後的密碼重新執行一次登入操作,重建Session,並更新客戶端上Cookie中存放的的Session ID,而這個操作是發生在使用者請求一個需要身份驗證的頁面資源的背後,對於使用者來講是透明的,於是就達到了“記住我的登入狀態”的目的了。