Session與Cookie的區(qū)別
Session與Cookie的區(qū)別zhuan(http://www.imtinewlife.com/BBS/ShowPost.asp?ThreadID=2768)
為什么會有cookie呢,大家都知道,http是無狀態(tài)的協(xié)議,客戶每次讀取
web頁面時,服務(wù)器都打開新的會話,而且服務(wù)器也不會自動維護客戶的上下文信息,那么要怎么才能實現(xiàn)網(wǎng)上商店中的購物車呢,session就是一種保存
上下文信息的機制,它是針對每一個用戶的,變量的值保存在服務(wù)器端,通過
SessionID來區(qū)分不同的客戶,session是以cookie或URL重寫為基礎(chǔ)的,默認(rèn)使用cookie來實現(xiàn),系統(tǒng)會創(chuàng)造一個名為
JSESSIONID的輸出cookie,我們叫做session cookie,以區(qū)別persistent
cookies,也就是我們通常所說的cookie,注意session
cookie是存儲于瀏覽器內(nèi)存中的,并不是寫到硬盤上的,這也就是我們剛才看到的JSESSIONID,我們通常情是看不到JSESSIONID的,但
是當(dāng)我們把瀏覽器的cookie禁止后,WEB服務(wù)器會采用URL重寫的方式傳遞Sessionid,我們就可以在地址欄看到sessionid=
KWJHUG6JJM65HS2K6之類的字符串。
明白了原理,我們就可以很容易的分辨出persistent cookies和session
cookie的區(qū)別了,網(wǎng)上那些關(guān)于兩者安全性的討論也就一目了然了,session
cookie針對某一次會話而言,會話結(jié)束session cookie也就隨著消失了,而persistent
cookie只是存在于客戶端硬盤上的一段文本(通常是加密的),而且可能會遭到cookie欺騙以及針對cookie的跨站腳本攻擊,自然不如
session cookie安全了。
通常session
cookie是不能跨窗口使用的,當(dāng)你新開了一個瀏覽器窗口進入相同頁面時,系統(tǒng)會賦予你一個新的sessionid,這樣我們信息共享的目的就達(dá)不到
了,此時我們可以先把sessionid保存在persistent
cookie中,然后在新窗口中讀出來,就可以得到上一個窗口SessionID了,這樣通過session
cookie和persistent cookie的結(jié)合我們就實現(xiàn)了跨窗口的session tracking(會話跟蹤)。
在一些WEB開發(fā)的書中,往往只是簡單的把Session和cookie作為兩種并列的http傳送信息的方式,session
cookies位于服務(wù)器端,persistent
cookie位于客戶端,可是session又是以cookie為基礎(chǔ)的,明白的兩者之間的聯(lián)系和區(qū)別,我們就不難選擇合適的技術(shù)來開發(fā)WEB
service了。
(1)
session總是放在服務(wù)器上的,每個客戶會跟一個sessionID對應(yīng)。因為HTTP是無連接的,如何區(qū)分同一個客戶的多次請求呢,就需要客戶端每次發(fā)請求的時候,發(fā)送相應(yīng)的sessionID。
通常情況下,sessionID在客戶端以cookie的形式保存。如果瀏覽器靜止了cookie,客戶端再向服務(wù)器發(fā)請求的時候,就不會發(fā)送sessionID,因此服務(wù)器就會將這個請求作為一個新客戶,所以就會出現(xiàn)session值丟失的假象。
這
時候出現(xiàn)一個問題,如果客戶瀏覽器不支持cookie,怎么辦?J2EE提供的另一個辦法就是URL重寫,寫超鏈接的時侯,總是用
response.encodeURL(url),連接就會變成*.jsp?sessionID=......,完成了原來用cookie完成的功能。
J2EE建議,不論客戶瀏覽器是否支持cookie,服務(wù)器端編程都建議使用URL重寫。
(2)
web上用的都是非連接的網(wǎng)絡(luò)協(xié)議
session 是存在服務(wù)器上的
每個session有一個唯一的session ID(為了標(biāo)識他是那個客戶端的)
在啟動session的同時,會在客戶端生成cookie,服務(wù)器把session ID加到cookie中
每次服務(wù)器和客戶端交互的時候,就是從cookie中取得session ID 來定位服務(wù)器上的session
這樣只要你的cookie不過期,服務(wù)器上有你的session,就不會出問題
(3)
JSP實現(xiàn)在瀏覽器關(guān)閉cookies情況下的會話管理
通常,會話管理是通過服務(wù)器將 Session ID 作為一個 cookie 存儲在用戶的 Web 瀏覽器中來唯一標(biāo)識每個用戶會話。如果瀏覽器不支持 cookies,或者將瀏覽器設(shè)置為不接受 cookies,我們可以通過 URL 重寫來實現(xiàn)會話管理。
實質(zhì)上 URL 重寫是通過向 URL 連接添加參數(shù),并把 session ID 作為值包含在連接中。然而,為使這生效,你需要為你的 servlet 響應(yīng)部分的每個連接添加 session ID 。
把 session ID 加到一個連接可以使用一對方法來簡化:response.encodeURL() 使 URL 包含 session ID,如果你需要使用重定向,可以使用 response.encodeRedirectURL () 來對 URL 進行編碼。
encodeURL () 及 encodeRedirectedURL () 方法首先判斷 cookies 是否被瀏覽器支持;如果支持,則參數(shù) URL 被原樣返回,session ID 將通過 cookies 來維持。
來看下面的例子,兩個 JSP 文件:hello1.jsp 和 hello2.jsp,及它們之間的影響。我們在 hello1.jsp 中簡單的創(chuàng)建一個會話,并在 session 中存儲一個對象實例。接著用戶可以點擊頁面的連接到達(dá) hello2.jsp。在 hello2.jsp 中,我們從 session 中獲取原先放置的對象并顯示它的內(nèi)容。注意,我們在 hello1.jsp 中調(diào)用了 encodeURL() 方法來獲得 hello2.jsp 的鏈接,使得在瀏覽器停用 cookies 的情況下,session ID 自動添加到 URL,hello2.jsp 仍能得到 session 對象。
首先在啟用 cookies 的情況下運行。然后關(guān)閉對 cookie 的支持,重啟瀏覽器,再運行一次。每次你都可以看到會話管理在起作用,并能在頁之間傳遞信息。
注意,如果你想讓這個例子能在關(guān)閉了 cookies 的瀏覽器中工作,你的 JSP 引擎必須支持 URL 重寫。
---------------------------------------------------------------------------------------------------------------------------------------
cookie 機制。正統(tǒng)的cookie分發(fā)是通過擴展HTTP協(xié)議來實現(xiàn)的,服務(wù)器通過在HTTP的響應(yīng)頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應(yīng)的 cookie。然而純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie。而cookie的使用是由瀏覽器按照一定的原則 在后臺自動發(fā)送給服務(wù)器的。瀏覽器檢查所有存儲的cookie,如果某個cookie所聲明的作用范圍大于等于將要請求的資源所在的位置,則把該 cookie附在請求資源的HTTP請求頭上發(fā)送給服務(wù)器。
cookie的內(nèi)容主要包括:名字,值,過期時間,路徑和域。路徑與域一 起構(gòu)成cookie的作用范圍。若不設(shè)置過期時間,則表示這個cookie的生命期為瀏覽器會話期間,關(guān)閉瀏覽器窗口,cookie就消失。這種生命期為 瀏覽器會話期的cookie被稱為會話cookie。會話cookie一般不存儲在硬盤上而是保存在內(nèi)存里,當(dāng)然這種行為并不是規(guī)范規(guī)定的。若設(shè)置了過期 時間,瀏覽器就會把cookie保存到硬盤上,關(guān)閉后再次打開瀏覽器,這些cookie仍然有效直到超過設(shè)定的過期時間。存儲在硬盤上的cookie可以 在不同的瀏覽器進程間共享,比如兩個IE窗口。而對于保存在內(nèi)存里的cookie,不同的瀏覽器有不同的處理方式
session機制。session機制是一種服務(wù)器端的機制,服務(wù)器使用一種類似于散列表的結(jié)構(gòu)(也可能就是使用散列表)來保存信息。
當(dāng) 程序需要為某個客戶端的請求創(chuàng)建一個session時,服務(wù)器首先檢查這個客戶端的請求里是否已包含了一個session標(biāo)識(稱為 sessionid),如果已包含則說明以前已經(jīng)為此客戶端創(chuàng)建過session,服務(wù)器就按照sessionid把這個session檢索出來使用(檢 索不到,會新建一個),如果客戶端請求不包含sessionid,則為此客戶端創(chuàng)建一個session并且生成一個與此session相關(guān)聯(lián)的 session id,sessionid的值應(yīng)該是一個既不會重復(fù),又不容易被找到規(guī)律以仿造的字符串,這個session id將被在本次響應(yīng)中返回給客戶端保存。
保存這個sessionid的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照 規(guī)則把這個標(biāo)識發(fā)揮給服務(wù)器。一般這個cookie的名字都是類似于SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在 cookie被禁止時仍然能夠把sessionid傳遞回服務(wù)器。
經(jīng)常被使用的一種技術(shù)叫做URL重寫,就是把session id直接附加在URL路徑的后面。還有一種技術(shù)叫做表單隱藏字段。就是服務(wù)器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把sessionid傳遞回服務(wù)器。比如:
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid"
value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
實際上這種技術(shù)可以簡單的用對action應(yīng)用URL重寫來代替。