1. 程式人生 > >Session與Cookie的區別和聯絡

Session與Cookie的區別和聯絡

一、關於Session

Session 是存放在伺服器端的,類似於Session結構來存放使用者資料,當瀏覽器 第一次傳送請求時,伺服器自動生成了一個Session和一個Session ID用來唯一標識這個Session,並將其通過響應傳送到瀏覽器。當瀏覽器第二次傳送請求,會將前一次伺服器響應中的Session ID放在請求中一併傳送到伺服器上,伺服器從請求中提取出Session ID,並和儲存的所有Session ID進行對比,找到這個使用者對應的Session。

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

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

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

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

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

二:Session與Cookie區別和聯絡

cookie資料儲存在客戶端,session資料儲存在伺服器端。

web伺服器端如果使用的是session,那麼所有的資料都儲存在伺服器上面,客戶端每次請求伺服器的時候會發送 當前會話的sessionid,伺服器根據當前sessionid判斷相應的使用者資料標誌,以確定使用者是否登入,或具有某種許可權。由於資料是儲存在伺服器 上面,所以你不能偽造,但是如果你能夠獲取某個登入使用者的sessionid,用特殊的瀏覽器偽造該使用者的請求也是能夠成功的。sessionid是服務 器和客戶端連結時候隨機分配的,一般來說是不會有重複,但如果有大量的併發請求,也不是沒有重複的可能性。出現的機率小,但是絕對不排除這樣的可能性

如果瀏覽器使用的是 cookie,那麼所有的資料都儲存在瀏覽器端,比如你登入以後,伺服器設定了 cookie使用者名稱,那麼當你再次請求伺服器的時候,瀏覽器會將使用者名稱一塊傳送給伺服器,這些變數有一定的特殊標記。服 務器會解釋為 cookie變數。所以只要不關閉瀏覽器,那麼 cookie變數便一直是有效的,所以能夠保證長時間不掉線。如果你能夠截獲某個使用者的 cookie變數,然後偽造一個數據包傳送過去,那麼伺服器還是認為你是合法的。所以,使用 cookie被攻擊的可能性比較大。如果設定了的有效時間,那麼它會將 cookie儲存在客戶端的硬碟上,下次再訪問該網站的時候,瀏覽器先檢查有沒有 cookie,如果有的話,就讀取該 cookie,然後傳送給伺服器。如果你在機器上面儲存了某個論壇 cookie,有效期是一年,如果有人入侵你的機器,將你的 cookie拷走,然後放在他的瀏覽器的目錄下面,那麼他登入該網站的時候就是用你的的身份登入的。所以 cookie是可以偽造的。當然,偽造的時候需要主意,直接copy cookie檔案到 cookie目錄,瀏覽器是不認的,他有一個index.dat檔案,儲存了 cookie檔案的建立時間,以及是否有修改,所以你必須先要有該網站的 cookie檔案,並且要從保證時間上騙過瀏覽器,曾經在學校的vbb論壇上面做過試驗,copy別人的 cookie登入,冒用了別人的名義發帖子,完全沒有問題。

Session是由應用伺服器維持的一個伺服器端的儲存空間,使用者在連線伺服器時,會由伺服器生成一個唯一的SessionID,用該SessionID 為識別符號來存取伺服器端的Session儲存空間。而SessionID這一資料則是儲存到客戶端,用Cookie儲存的,使用者提交頁面時,會將這一 SessionID提交到伺服器端,來存取Session資料。這一過程,是不用開發人員干預的。所以一旦客戶端禁用Cookie,那麼Session也會失效。

伺服器也可以通過URL重寫的方式來傳遞SessionID的值,因此不是完全依賴Cookie。如果客戶端Cookie禁用,則伺服器可以自動通過重寫URL的方式來儲存Session的值,並且這個過程對程式設計師透明。

即使不寫Cookie,在使用request.getCookies();取出的Cookie陣列的長度也是1,而這個Cookie的名字就是JSESSIONID,還有一個很長的二進位制的字串,是SessionID的值。

例子:

cookie[]cookies = request.getCookies();

if (cookies.lenght == 0 || cookies == null){

doStuffForNewbie();//沒有訪問過 

}else{

doStuffForReturnVisitor(); //已經訪問過了

}

Cookies是屬於Session物件的一種。但有不同,Cookies不會佔伺服器資源,是存在客服端記憶體或者一個cookie的文字檔案中;而“Session”則會佔用伺服器資源。所以,儘量不要使用Session,而使用Cookies。但是我們一般認為cookie是不可靠的,session是可靠地,但是目前很多著名的站點也都以來cookie。有時候為了解決禁用cookie後的頁面處理,通常採用url重寫技術,呼叫session中大量有用的方法從session中獲取資料後置入頁面。

二:Cookies與Session的應用場景

Cookies的安全效能一直是倍受爭議的。雖然Cookies是儲存在本機上的,但是其資訊的完全可見性且易於本地編輯性,往往可以引起很多的安全問題。所以Cookies到底該不該用,到底該怎樣用,就有了一個需要給定的底線。

先來看看,網站的敏感資料有哪些。

登陸驗證資訊。一般採用Session(“Logon”)=true or false的形式。 
使用者的各種私人資訊,比如姓名等,某種情況下,需要儲存在Session裡 
需要在頁面間傳遞的內容資訊,比如調查工作需要分好幾步。每一步的資訊都儲存在Session裡,最後在統一更新到資料庫。

當然還會有很多,這裡列舉一些比較典型的 
假如,一個人孤僻到不想碰Session,因為他認為,如果使用者萬一不小心關閉了瀏覽器,那麼之前儲存的資料就全部丟失了。所以,他出於好意,決定把這些用Session的地方,都改成用Cookies來儲存,這完全是可行的,且基本操作和用Session一模一樣。那麼,下面就針對以上的3個典型例子,做一個分析 
很顯然,只要某個有意非法入侵者,知道該網站驗證登陸資訊的Session變數是什麼,那麼他就可以事先編輯好該Cookies,放入到Cookies目錄中,這樣就可以順利通過驗證了。這是不是很可怕? 
Cookies完全是可見的,即使程式設計師設定了Cookies的生存週期(比如只在使用者會話有效期內有效),它也是不安全的。假設,使用者忘了關瀏覽器 或者一個惡意者硬性把使用者給打暈,那使用者的損失將是巨大的。 
這點如上點一樣,很容易被它人竊取重要的私人資訊。但,其還有一個問題所在是,可能這些資料資訊量太大,而使得Cookies的檔案大小劇增。這可不是使用者希望所看到的。

顯然,Cookies並不是那麼一塊好啃的小甜餅。但,Cookies的存在,當然有其原因。它給予程式設計師更多發揮程式設計才能的空間。所以,使用Cookies改有個底線。這個底線一般來說,遵循以下原則。 
不要儲存私人資訊。 
任何重要資料,最好通過加密形式來儲存資料(最簡單的可以用URLEncode,當然也可以用完善的可逆加密方式)。 
是否儲存登陸資訊,需有使用者自行選擇。 
長於10K的資料,不要用到Cookies。 
也不要用Cookies來玩點讓客戶驚喜的小遊戲。