天天看點

記住我的登入狀态 實作原理

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裡面存 放的使用者名和加密之後的密碼(更好的做法是不存密碼,見另一文章:http://canann.iteye.com/admin/blogs/1940946)重新執行一次登入操作,重建Session,并更新用戶端上Cookie中存放的的Session ID,而這個操作是發生在使用者請求一個需要身份驗證的頁面資源的背後,對于使用者來講是透明的,于是就達到了“記住我的登入狀态”的目的了。